|
@@ -1,17863 +0,0 @@
|
|
|
---- a/.gitignore
|
|
|
-+++ b/.gitignore
|
|
|
-@@ -5,9 +5,6 @@
|
|
|
- *.so.1
|
|
|
- arch/*/bits/alltypes.h
|
|
|
- config.mak
|
|
|
--include/bits
|
|
|
--tools/musl-gcc
|
|
|
--tools/musl-clang
|
|
|
--tools/ld.musl-clang
|
|
|
- lib/musl-gcc.specs
|
|
|
- src/internal/version.h
|
|
|
-+/obj/
|
|
|
---- a/Makefile
|
|
|
-+++ b/Makefile
|
|
|
-@@ -8,6 +8,7 @@
|
|
|
- # Do not make changes here.
|
|
|
- #
|
|
|
-
|
|
|
-+srcdir = .
|
|
|
- exec_prefix = /usr/local
|
|
|
- bindir = $(exec_prefix)/bin
|
|
|
-
|
|
|
-@@ -16,31 +17,42 @@ includedir = $(prefix)/include
|
|
|
- libdir = $(prefix)/lib
|
|
|
- syslibdir = /lib
|
|
|
-
|
|
|
--SRCS = $(sort $(wildcard src/*/*.c arch/$(ARCH)/src/*.c))
|
|
|
--OBJS = $(SRCS:.c=.o)
|
|
|
-+BASE_SRCS = $(sort $(wildcard $(srcdir)/src/*/*.c))
|
|
|
-+BASE_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(BASE_SRCS)))
|
|
|
-+ARCH_SRCS = $(wildcard $(srcdir)/src/*/$(ARCH)/*.[csS])
|
|
|
-+ARCH_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(ARCH_SRCS)))
|
|
|
-+REPLACED_OBJS = $(sort $(subst /$(ARCH)/,/,$(ARCH_OBJS)))
|
|
|
-+LDSO_SRCS = $(sort $(wildcard $(srcdir)/ldso/*.c))
|
|
|
-+LDSO_OBJS = $(patsubst $(srcdir)/%,obj/%.lo,$(basename $(LDSO_SRCS)))
|
|
|
-+OBJS = $(addprefix obj/, $(filter-out $(REPLACED_OBJS), $(sort $(BASE_OBJS) $(ARCH_OBJS))))
|
|
|
-+AOBJS = $(OBJS)
|
|
|
- LOBJS = $(OBJS:.o=.lo)
|
|
|
--GENH = include/bits/alltypes.h
|
|
|
--GENH_INT = src/internal/version.h
|
|
|
--IMPH = src/internal/stdio_impl.h src/internal/pthread_impl.h src/internal/libc.h
|
|
|
-+GENH = obj/include/bits/alltypes.h
|
|
|
-+GENH_INT = obj/src/internal/version.h
|
|
|
-+IMPH = $(addprefix $(srcdir)/, src/internal/stdio_impl.h src/internal/pthread_impl.h src/internal/libc.h)
|
|
|
-
|
|
|
--LDFLAGS =
|
|
|
-+LDFLAGS =
|
|
|
-+LDFLAGS_AUTO =
|
|
|
- LIBCC = -lgcc
|
|
|
- CPPFLAGS =
|
|
|
--CFLAGS = -Os -pipe
|
|
|
-+CFLAGS =
|
|
|
-+CFLAGS_AUTO = -Os -pipe
|
|
|
- CFLAGS_C99FSE = -std=c99 -ffreestanding -nostdinc
|
|
|
-
|
|
|
- CFLAGS_ALL = $(CFLAGS_C99FSE)
|
|
|
--CFLAGS_ALL += -D_XOPEN_SOURCE=700 -I./arch/$(ARCH) -I./src/internal -I./include
|
|
|
--CFLAGS_ALL += $(CPPFLAGS) $(CFLAGS)
|
|
|
--CFLAGS_ALL_STATIC = $(CFLAGS_ALL)
|
|
|
--CFLAGS_ALL_SHARED = $(CFLAGS_ALL) -fPIC -DSHARED
|
|
|
-+CFLAGS_ALL += -D_XOPEN_SOURCE=700 -I$(srcdir)/arch/$(ARCH) -I$(srcdir)/arch/generic -Iobj/src/internal -I$(srcdir)/src/internal -Iobj/include -I$(srcdir)/include
|
|
|
-+CFLAGS_ALL += $(CPPFLAGS) $(CFLAGS_AUTO) $(CFLAGS)
|
|
|
-+
|
|
|
-+LDFLAGS_ALL = $(LDFLAGS_AUTO) $(LDFLAGS)
|
|
|
-
|
|
|
- AR = $(CROSS_COMPILE)ar
|
|
|
- RANLIB = $(CROSS_COMPILE)ranlib
|
|
|
--INSTALL = ./tools/install.sh
|
|
|
-+INSTALL = $(srcdir)/tools/install.sh
|
|
|
-
|
|
|
--ARCH_INCLUDES = $(wildcard arch/$(ARCH)/bits/*.h)
|
|
|
--ALL_INCLUDES = $(sort $(wildcard include/*.h include/*/*.h) $(GENH) $(ARCH_INCLUDES:arch/$(ARCH)/%=include/%))
|
|
|
-+ARCH_INCLUDES = $(wildcard $(srcdir)/arch/$(ARCH)/bits/*.h)
|
|
|
-+GENERIC_INCLUDES = $(wildcard $(srcdir)/arch/generic/bits/*.h)
|
|
|
-+INCLUDES = $(wildcard $(srcdir)/include/*.h $(srcdir)/include/*/*.h)
|
|
|
-+ALL_INCLUDES = $(sort $(INCLUDES:$(srcdir)/%=%) $(GENH:obj/%=%) $(ARCH_INCLUDES:$(srcdir)/arch/$(ARCH)/%=include/%) $(GENERIC_INCLUDES:$(srcdir)/arch/generic/%=include/%))
|
|
|
-
|
|
|
- EMPTY_LIB_NAMES = m rt pthread crypt util xnet resolv dl
|
|
|
- EMPTY_LIBS = $(EMPTY_LIB_NAMES:%=lib/lib%.a)
|
|
|
-@@ -49,7 +61,7 @@ STATIC_LIBS = lib/libc.a
|
|
|
- SHARED_LIBS = lib/libc.so
|
|
|
- TOOL_LIBS = lib/musl-gcc.specs
|
|
|
- ALL_LIBS = $(CRT_LIBS) $(STATIC_LIBS) $(SHARED_LIBS) $(EMPTY_LIBS) $(TOOL_LIBS)
|
|
|
--ALL_TOOLS = tools/musl-gcc
|
|
|
-+ALL_TOOLS = obj/musl-gcc
|
|
|
-
|
|
|
- WRAPCC_GCC = gcc
|
|
|
- WRAPCC_CLANG = clang
|
|
|
-@@ -58,122 +70,128 @@ LDSO_PATHNAME = $(syslibdir)/ld-musl-$(A
|
|
|
-
|
|
|
- -include config.mak
|
|
|
-
|
|
|
-+ifeq ($(ARCH),)
|
|
|
-+$(error Please set ARCH in config.mak before running make.)
|
|
|
-+endif
|
|
|
-+
|
|
|
- all: $(ALL_LIBS) $(ALL_TOOLS)
|
|
|
-
|
|
|
-+OBJ_DIRS = $(sort $(patsubst %/,%,$(dir $(ALL_LIBS) $(ALL_TOOLS) $(OBJS) $(LDSO_OBJS) $(GENH) $(GENH_INT))) $(addprefix obj/, crt crt/$(ARCH) include))
|
|
|
-+
|
|
|
-+$(ALL_LIBS) $(ALL_TOOLS) $(CRT_LIBS:lib/%=obj/crt/%) $(OBJS) $(LOBJS) $(GENH) $(GENH_INT): | $(OBJ_DIRS)
|
|
|
-+
|
|
|
-+$(OBJ_DIRS):
|
|
|
-+ mkdir -p $@
|
|
|
-+
|
|
|
- install: install-libs install-headers install-tools
|
|
|
-
|
|
|
- clean:
|
|
|
-- rm -f crt/*.o
|
|
|
-- rm -f $(OBJS)
|
|
|
-- rm -f $(LOBJS)
|
|
|
-- rm -f $(ALL_LIBS) lib/*.[ao] lib/*.so
|
|
|
-- rm -f $(ALL_TOOLS)
|
|
|
-- rm -f $(GENH) $(GENH_INT)
|
|
|
-- rm -f include/bits
|
|
|
-+ rm -rf obj lib
|
|
|
-
|
|
|
- distclean: clean
|
|
|
- rm -f config.mak
|
|
|
-
|
|
|
--include/bits:
|
|
|
-- @test "$(ARCH)" || { echo "Please set ARCH in config.mak before running make." ; exit 1 ; }
|
|
|
-- ln -sf ../arch/$(ARCH)/bits $@
|
|
|
-+obj/include/bits/alltypes.h: $(srcdir)/arch/$(ARCH)/bits/alltypes.h.in $(srcdir)/include/alltypes.h.in $(srcdir)/tools/mkalltypes.sed
|
|
|
-+ sed -f $(srcdir)/tools/mkalltypes.sed $(srcdir)/arch/$(ARCH)/bits/alltypes.h.in $(srcdir)/include/alltypes.h.in > $@
|
|
|
-
|
|
|
--include/bits/alltypes.h.in: include/bits
|
|
|
-+obj/src/internal/version.h: $(wildcard $(srcdir)/VERSION $(srcdir)/.git)
|
|
|
-+ printf '#define VERSION "%s"\n' "$$(cd $(srcdir); sh tools/version.sh)" > $@
|
|
|
-
|
|
|
--include/bits/alltypes.h: include/bits/alltypes.h.in include/alltypes.h.in tools/mkalltypes.sed
|
|
|
-- sed -f tools/mkalltypes.sed include/bits/alltypes.h.in include/alltypes.h.in > $@
|
|
|
-+obj/src/internal/version.o obj/src/internal/version.lo: obj/src/internal/version.h
|
|
|
-
|
|
|
--src/internal/version.h: $(wildcard VERSION .git)
|
|
|
-- printf '#define VERSION "%s"\n' "$$(sh tools/version.sh)" > $@
|
|
|
-+obj/crt/rcrt1.o obj/ldso/dlstart.lo obj/ldso/dynlink.lo: $(srcdir)/src/internal/dynlink.h $(srcdir)/arch/$(ARCH)/reloc.h
|
|
|
-
|
|
|
--src/internal/version.lo: src/internal/version.h
|
|
|
-+obj/crt/crt1.o obj/crt/scrt1.o obj/crt/rcrt1.o obj/ldso/dlstart.lo: $(srcdir)/arch/$(ARCH)/crt_arch.h
|
|
|
-
|
|
|
--crt/rcrt1.o src/ldso/dlstart.lo src/ldso/dynlink.lo: src/internal/dynlink.h arch/$(ARCH)/reloc.h
|
|
|
-+obj/crt/rcrt1.o: $(srcdir)/ldso/dlstart.c
|
|
|
-
|
|
|
--crt/crt1.o crt/Scrt1.o crt/rcrt1.o src/ldso/dlstart.lo: $(wildcard arch/$(ARCH)/crt_arch.h)
|
|
|
-+obj/crt/Scrt1.o obj/crt/rcrt1.o: CFLAGS_ALL += -fPIC
|
|
|
-
|
|
|
--crt/rcrt1.o: src/ldso/dlstart.c
|
|
|
-+obj/crt/$(ARCH)/crti.o: $(srcdir)/crt/$(ARCH)/crti.s
|
|
|
-
|
|
|
--crt/Scrt1.o crt/rcrt1.o: CFLAGS += -fPIC
|
|
|
-+obj/crt/$(ARCH)/crtn.o: $(srcdir)/crt/$(ARCH)/crtn.s
|
|
|
-
|
|
|
--OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=src/%))
|
|
|
--$(OPTIMIZE_SRCS:%.c=%.o) $(OPTIMIZE_SRCS:%.c=%.lo): CFLAGS += -O3
|
|
|
-+OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=$(srcdir)/src/%))
|
|
|
-+$(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.o) $(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.lo): CFLAGS += -O3
|
|
|
-
|
|
|
- MEMOPS_SRCS = src/string/memcpy.c src/string/memmove.c src/string/memcmp.c src/string/memset.c
|
|
|
--$(MEMOPS_SRCS:%.c=%.o) $(MEMOPS_SRCS:%.c=%.lo): CFLAGS += $(CFLAGS_MEMOPS)
|
|
|
-+$(MEMOPS_SRCS:%.c=obj/%.o) $(MEMOPS_SRCS:%.c=obj/%.lo): CFLAGS_ALL += $(CFLAGS_MEMOPS)
|
|
|
-
|
|
|
- NOSSP_SRCS = $(wildcard crt/*.c) \
|
|
|
- src/env/__libc_start_main.c src/env/__init_tls.c \
|
|
|
-- src/thread/__set_thread_area.c src/env/__stack_chk_fail.c \
|
|
|
-- src/string/memset.c src/string/memcpy.c \
|
|
|
-- src/ldso/dlstart.c src/ldso/dynlink.c
|
|
|
--$(NOSSP_SRCS:%.c=%.o) $(NOSSP_SRCS:%.c=%.lo): CFLAGS += $(CFLAGS_NOSSP)
|
|
|
-+ src/env/__stack_chk_fail.c \
|
|
|
-+ src/thread/__set_thread_area.c src/thread/$(ARCH)/__set_thread_area.c \
|
|
|
-+ src/string/memset.c src/string/$(ARCH)/memset.c \
|
|
|
-+ src/string/memcpy.c src/string/$(ARCH)/memcpy.c \
|
|
|
-+ ldso/dlstart.c ldso/dynlink.c
|
|
|
-+$(NOSSP_SRCS:%.c=obj/%.o) $(NOSSP_SRCS:%.c=obj/%.lo): CFLAGS_ALL += $(CFLAGS_NOSSP)
|
|
|
-
|
|
|
--$(CRT_LIBS:lib/%=crt/%): CFLAGS += -DCRT
|
|
|
-+$(CRT_LIBS:lib/%=obj/crt/%): CFLAGS_ALL += -DCRT
|
|
|
-
|
|
|
--# This incantation ensures that changes to any subarch asm files will
|
|
|
--# force the corresponding object file to be rebuilt, even if the implicit
|
|
|
--# rule below goes indirectly through a .sub file.
|
|
|
--define mkasmdep
|
|
|
--$(dir $(patsubst %/,%,$(dir $(1))))$(notdir $(1:.s=.o)): $(1)
|
|
|
--endef
|
|
|
--$(foreach s,$(wildcard src/*/$(ARCH)*/*.s),$(eval $(call mkasmdep,$(s))))
|
|
|
-+$(LOBJS) $(LDSO_OBJS): CFLAGS_ALL += -fPIC
|
|
|
-+
|
|
|
-+CC_CMD = $(CC) $(CFLAGS_ALL) -c -o $@ $<
|
|
|
-
|
|
|
- # Choose invocation of assembler to be used
|
|
|
--# $(1) is input file, $(2) is output file, $(3) is assembler flags
|
|
|
- ifeq ($(ADD_CFI),yes)
|
|
|
-- AS_CMD = LC_ALL=C awk -f tools/add-cfi.common.awk -f tools/add-cfi.$(ARCH).awk $< | $(CC) -x assembler -c -o $@ -
|
|
|
-+ AS_CMD = LC_ALL=C awk -f $(srcdir)/tools/add-cfi.common.awk -f $(srcdir)/tools/add-cfi.$(ARCH).awk $< | $(CC) $(CFLAGS_ALL) -x assembler -c -o $@ -
|
|
|
- else
|
|
|
-- AS_CMD = $(CC) -c -o $@ $<
|
|
|
-+ AS_CMD = $(CC_CMD)
|
|
|
- endif
|
|
|
-
|
|
|
--%.o: $(ARCH)$(ASMSUBARCH)/%.sub
|
|
|
-- $(CC) $(CFLAGS_ALL_STATIC) -c -o $@ $(dir $<)$(shell cat $<)
|
|
|
-+obj/%.o: $(srcdir)/%.s
|
|
|
-+ $(AS_CMD)
|
|
|
-
|
|
|
--%.o: $(ARCH)/%.s
|
|
|
-- $(AS_CMD) $(CFLAGS_ALL_STATIC)
|
|
|
-+obj/%.o: $(srcdir)/%.S
|
|
|
-+ $(CC_CMD)
|
|
|
-
|
|
|
--%.o: %.c $(GENH) $(IMPH)
|
|
|
-- $(CC) $(CFLAGS_ALL_STATIC) -c -o $@ $<
|
|
|
-+obj/%.o: $(srcdir)/%.c $(GENH) $(IMPH)
|
|
|
-+ $(CC_CMD)
|
|
|
-
|
|
|
--%.lo: $(ARCH)$(ASMSUBARCH)/%.sub
|
|
|
-- $(CC) $(CFLAGS_ALL_SHARED) -c -o $@ $(dir $<)$(shell cat $<)
|
|
|
-+obj/%.lo: $(srcdir)/%.s
|
|
|
-+ $(AS_CMD)
|
|
|
-
|
|
|
--%.lo: $(ARCH)/%.s
|
|
|
-- $(AS_CMD) $(CFLAGS_ALL_SHARED)
|
|
|
-+obj/%.lo: $(srcdir)/%.S
|
|
|
-+ $(CC_CMD)
|
|
|
-
|
|
|
--%.lo: %.c $(GENH) $(IMPH)
|
|
|
-- $(CC) $(CFLAGS_ALL_SHARED) -c -o $@ $<
|
|
|
-+obj/%.lo: $(srcdir)/%.c $(GENH) $(IMPH)
|
|
|
-+ $(CC_CMD)
|
|
|
-
|
|
|
--lib/libc.so: $(LOBJS)
|
|
|
-- $(CC) $(CFLAGS_ALL_SHARED) $(LDFLAGS) -nostdlib -shared \
|
|
|
-+lib/libc.so: $(LOBJS) $(LDSO_OBJS)
|
|
|
-+ $(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -nostdlib -shared \
|
|
|
- -Wl,-e,_dlstart -Wl,-Bsymbolic-functions \
|
|
|
-- -o $@ $(LOBJS) $(LIBCC)
|
|
|
-+ -o $@ $(LOBJS) $(LDSO_OBJS) $(LIBCC)
|
|
|
-
|
|
|
--lib/libc.a: $(OBJS)
|
|
|
-+lib/libc.a: $(AOBJS)
|
|
|
- rm -f $@
|
|
|
-- $(AR) rc $@ $(OBJS)
|
|
|
-+ $(AR) rc $@ $(AOBJS)
|
|
|
- $(RANLIB) $@
|
|
|
-
|
|
|
- $(EMPTY_LIBS):
|
|
|
- rm -f $@
|
|
|
- $(AR) rc $@
|
|
|
-
|
|
|
--lib/%.o: crt/%.o
|
|
|
-+lib/%.o: obj/crt/%.o
|
|
|
- cp $< $@
|
|
|
-
|
|
|
--lib/musl-gcc.specs: tools/musl-gcc.specs.sh config.mak
|
|
|
-+lib/crti.o: obj/crt/$(ARCH)/crti.o
|
|
|
-+ cp $< $@
|
|
|
-+
|
|
|
-+lib/crtn.o: obj/crt/$(ARCH)/crtn.o
|
|
|
-+ cp $< $@
|
|
|
-+
|
|
|
-+lib/musl-gcc.specs: $(srcdir)/tools/musl-gcc.specs.sh config.mak
|
|
|
- sh $< "$(includedir)" "$(libdir)" "$(LDSO_PATHNAME)" > $@
|
|
|
-
|
|
|
--tools/musl-gcc: config.mak
|
|
|
-+obj/musl-gcc: config.mak
|
|
|
- printf '#!/bin/sh\nexec "$${REALGCC:-$(WRAPCC_GCC)}" "$$@" -specs "%s/musl-gcc.specs"\n' "$(libdir)" > $@
|
|
|
- chmod +x $@
|
|
|
-
|
|
|
--tools/%-clang: tools/%-clang.in config.mak
|
|
|
-+obj/%-clang: $(srcdir)/tools/%-clang.in config.mak
|
|
|
- sed -e 's!@CC@!$(WRAPCC_CLANG)!g' -e 's!@PREFIX@!$(prefix)!g' -e 's!@INCDIR@!$(includedir)!g' -e 's!@LIBDIR@!$(libdir)!g' -e 's!@LDSO@!$(LDSO_PATHNAME)!g' $< > $@
|
|
|
- chmod +x $@
|
|
|
-
|
|
|
--$(DESTDIR)$(bindir)/%: tools/%
|
|
|
-+$(DESTDIR)$(bindir)/%: obj/%
|
|
|
- $(INSTALL) -D $< $@
|
|
|
-
|
|
|
- $(DESTDIR)$(libdir)/%.so: lib/%.so
|
|
|
-@@ -182,10 +200,16 @@ $(DESTDIR)$(libdir)/%.so: lib/%.so
|
|
|
- $(DESTDIR)$(libdir)/%: lib/%
|
|
|
- $(INSTALL) -D -m 644 $< $@
|
|
|
-
|
|
|
--$(DESTDIR)$(includedir)/bits/%: arch/$(ARCH)/bits/%
|
|
|
-+$(DESTDIR)$(includedir)/bits/%: $(srcdir)/arch/$(ARCH)/bits/%
|
|
|
- $(INSTALL) -D -m 644 $< $@
|
|
|
-
|
|
|
--$(DESTDIR)$(includedir)/%: include/%
|
|
|
-+$(DESTDIR)$(includedir)/bits/%: $(srcdir)/arch/generic/bits/%
|
|
|
-+ $(INSTALL) -D -m 644 $< $@
|
|
|
-+
|
|
|
-+$(DESTDIR)$(includedir)/bits/%: obj/include/bits/%
|
|
|
-+ $(INSTALL) -D -m 644 $< $@
|
|
|
-+
|
|
|
-+$(DESTDIR)$(includedir)/%: $(srcdir)/include/%
|
|
|
- $(INSTALL) -D -m 644 $< $@
|
|
|
-
|
|
|
- $(DESTDIR)$(LDSO_PATHNAME): $(DESTDIR)$(libdir)/libc.so
|
|
|
-@@ -195,12 +219,12 @@ install-libs: $(ALL_LIBS:lib/%=$(DESTDIR
|
|
|
-
|
|
|
- install-headers: $(ALL_INCLUDES:include/%=$(DESTDIR)$(includedir)/%)
|
|
|
-
|
|
|
--install-tools: $(ALL_TOOLS:tools/%=$(DESTDIR)$(bindir)/%)
|
|
|
-+install-tools: $(ALL_TOOLS:obj/%=$(DESTDIR)$(bindir)/%)
|
|
|
-
|
|
|
- musl-git-%.tar.gz: .git
|
|
|
-- git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ $(patsubst musl-git-%.tar.gz,%,$@)
|
|
|
-+ git --git-dir=$(srcdir)/.git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ $(patsubst musl-git-%.tar.gz,%,$@)
|
|
|
-
|
|
|
- musl-%.tar.gz: .git
|
|
|
-- git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ v$(patsubst musl-%.tar.gz,%,$@)
|
|
|
-+ git --git-dir=$(srcdir)/.git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ v$(patsubst musl-%.tar.gz,%,$@)
|
|
|
-
|
|
|
- .PHONY: all clean install install-libs install-headers install-tools
|
|
|
---- a/arch/aarch64/atomic.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,206 +0,0 @@
|
|
|
--#ifndef _INTERNAL_ATOMIC_H
|
|
|
--#define _INTERNAL_ATOMIC_H
|
|
|
--
|
|
|
--#include <stdint.h>
|
|
|
--
|
|
|
--static inline int a_ctz_64(uint64_t x)
|
|
|
--{
|
|
|
-- __asm__(
|
|
|
-- " rbit %0, %1\n"
|
|
|
-- " clz %0, %0\n"
|
|
|
-- : "=r"(x) : "r"(x));
|
|
|
-- return x;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_ctz_l(unsigned long x)
|
|
|
--{
|
|
|
-- return a_ctz_64(x);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_barrier()
|
|
|
--{
|
|
|
-- __asm__ __volatile__("dmb ish");
|
|
|
--}
|
|
|
--
|
|
|
--static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
--{
|
|
|
-- void *old;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldxr %0,%3\n"
|
|
|
-- " cmp %0,%1\n"
|
|
|
-- " b.ne 1f\n"
|
|
|
-- " stxr %w0,%2,%3\n"
|
|
|
-- " cbnz %w0,1b\n"
|
|
|
-- " mov %0,%1\n"
|
|
|
-- "1: dmb ish\n"
|
|
|
-- : "=&r"(old)
|
|
|
-- : "r"(t), "r"(s), "Q"(*(long*)p)
|
|
|
-- : "memory", "cc");
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_cas(volatile int *p, int t, int s)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldxr %w0,%3\n"
|
|
|
-- " cmp %w0,%w1\n"
|
|
|
-- " b.ne 1f\n"
|
|
|
-- " stxr %w0,%w2,%3\n"
|
|
|
-- " cbnz %w0,1b\n"
|
|
|
-- " mov %w0,%w1\n"
|
|
|
-- "1: dmb ish\n"
|
|
|
-- : "=&r"(old)
|
|
|
-- : "r"(t), "r"(s), "Q"(*p)
|
|
|
-- : "memory", "cc");
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_swap(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old, tmp;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldxr %w0,%3\n"
|
|
|
-- " stxr %w1,%w2,%3\n"
|
|
|
-- " cbnz %w1,1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(old), "=&r"(tmp)
|
|
|
-- : "r"(v), "Q"(*x)
|
|
|
-- : "memory", "cc" );
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_fetch_add(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old, tmp;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldxr %w0,%3\n"
|
|
|
-- " add %w0,%w0,%w2\n"
|
|
|
-- " stxr %w1,%w0,%3\n"
|
|
|
-- " cbnz %w1,1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(old), "=&r"(tmp)
|
|
|
-- : "r"(v), "Q"(*x)
|
|
|
-- : "memory", "cc" );
|
|
|
-- return old-v;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_inc(volatile int *x)
|
|
|
--{
|
|
|
-- int tmp, tmp2;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldxr %w0,%2\n"
|
|
|
-- " add %w0,%w0,#1\n"
|
|
|
-- " stxr %w1,%w0,%2\n"
|
|
|
-- " cbnz %w1,1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(tmp), "=&r"(tmp2)
|
|
|
-- : "Q"(*x)
|
|
|
-- : "memory", "cc" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_dec(volatile int *x)
|
|
|
--{
|
|
|
-- int tmp, tmp2;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldxr %w0,%2\n"
|
|
|
-- " sub %w0,%w0,#1\n"
|
|
|
-- " stxr %w1,%w0,%2\n"
|
|
|
-- " cbnz %w1,1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(tmp), "=&r"(tmp2)
|
|
|
-- : "Q"(*x)
|
|
|
-- : "memory", "cc" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- int tmp, tmp2;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldxr %0,%3\n"
|
|
|
-- " and %0,%0,%2\n"
|
|
|
-- " stxr %w1,%0,%3\n"
|
|
|
-- " cbnz %w1,1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(tmp), "=&r"(tmp2)
|
|
|
-- : "r"(v), "Q"(*p)
|
|
|
-- : "memory", "cc" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and(volatile int *p, int v)
|
|
|
--{
|
|
|
-- int tmp, tmp2;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldxr %w0,%3\n"
|
|
|
-- " and %w0,%w0,%w2\n"
|
|
|
-- " stxr %w1,%w0,%3\n"
|
|
|
-- " cbnz %w1,1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(tmp), "=&r"(tmp2)
|
|
|
-- : "r"(v), "Q"(*p)
|
|
|
-- : "memory", "cc" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- int tmp, tmp2;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldxr %0,%3\n"
|
|
|
-- " orr %0,%0,%2\n"
|
|
|
-- " stxr %w1,%0,%3\n"
|
|
|
-- " cbnz %w1,1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(tmp), "=&r"(tmp2)
|
|
|
-- : "r"(v), "Q"(*p)
|
|
|
-- : "memory", "cc" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_l(volatile void *p, long v)
|
|
|
--{
|
|
|
-- return a_or_64(p, v);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or(volatile int *p, int v)
|
|
|
--{
|
|
|
-- int tmp, tmp2;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldxr %w0,%3\n"
|
|
|
-- " orr %w0,%w0,%w2\n"
|
|
|
-- " stxr %w1,%w0,%3\n"
|
|
|
-- " cbnz %w1,1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(tmp), "=&r"(tmp2)
|
|
|
-- : "r"(v), "Q"(*p)
|
|
|
-- : "memory", "cc" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_store(volatile int *p, int x)
|
|
|
--{
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- " str %w1,%0\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=m"(*p)
|
|
|
-- : "r"(x)
|
|
|
-- : "memory", "cc" );
|
|
|
--}
|
|
|
--
|
|
|
--#define a_spin a_barrier
|
|
|
--
|
|
|
--static inline void a_crash()
|
|
|
--{
|
|
|
-- *(volatile char *)0=0;
|
|
|
--}
|
|
|
--
|
|
|
--
|
|
|
--#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/aarch64/atomic_arch.h
|
|
|
-@@ -0,0 +1,73 @@
|
|
|
-+#define a_ll a_ll
|
|
|
-+static inline int a_ll(volatile int *p)
|
|
|
-+{
|
|
|
-+ int v;
|
|
|
-+ __asm__ __volatile__ ("ldaxr %w0,%1" : "=r"(v) : "Q"(*p));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_sc a_sc
|
|
|
-+static inline int a_sc(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int r;
|
|
|
-+ __asm__ __volatile__ ("stlxr %w0,%w1,%2" : "=&r"(r) : "r"(v), "Q"(*p) : "memory");
|
|
|
-+ return !r;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_barrier a_barrier
|
|
|
-+static inline void a_barrier()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__ ("dmb ish" : : : "memory");
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_cas a_cas
|
|
|
-+static inline int a_cas(volatile int *p, int t, int s)
|
|
|
-+{
|
|
|
-+ int old;
|
|
|
-+ do {
|
|
|
-+ old = a_ll(p);
|
|
|
-+ if (old != t) {
|
|
|
-+ a_barrier();
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
-+ } while (!a_sc(p, s));
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static inline void *a_ll_p(volatile void *p)
|
|
|
-+{
|
|
|
-+ void *v;
|
|
|
-+ __asm__ __volatile__ ("ldaxr %0, %1" : "=r"(v) : "Q"(*(void *volatile *)p));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static inline int a_sc_p(volatile int *p, void *v)
|
|
|
-+{
|
|
|
-+ int r;
|
|
|
-+ __asm__ __volatile__ ("stlxr %w0,%1,%2" : "=&r"(r) : "r"(v), "Q"(*(void *volatile *)p) : "memory");
|
|
|
-+ return !r;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_cas_p a_cas_p
|
|
|
-+static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
-+{
|
|
|
-+ void *old;
|
|
|
-+ do {
|
|
|
-+ old = a_ll_p(p);
|
|
|
-+ if (old != t) {
|
|
|
-+ a_barrier();
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
-+ } while (!a_sc_p(p, s));
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_ctz_64 a_ctz_64
|
|
|
-+static inline int a_ctz_64(uint64_t x)
|
|
|
-+{
|
|
|
-+ __asm__(
|
|
|
-+ " rbit %0, %1\n"
|
|
|
-+ " clz %0, %0\n"
|
|
|
-+ : "=r"(x) : "r"(x));
|
|
|
-+ return x;
|
|
|
-+}
|
|
|
---- a/arch/aarch64/bits/errno.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,134 +0,0 @@
|
|
|
--#define EPERM 1
|
|
|
--#define ENOENT 2
|
|
|
--#define ESRCH 3
|
|
|
--#define EINTR 4
|
|
|
--#define EIO 5
|
|
|
--#define ENXIO 6
|
|
|
--#define E2BIG 7
|
|
|
--#define ENOEXEC 8
|
|
|
--#define EBADF 9
|
|
|
--#define ECHILD 10
|
|
|
--#define EAGAIN 11
|
|
|
--#define ENOMEM 12
|
|
|
--#define EACCES 13
|
|
|
--#define EFAULT 14
|
|
|
--#define ENOTBLK 15
|
|
|
--#define EBUSY 16
|
|
|
--#define EEXIST 17
|
|
|
--#define EXDEV 18
|
|
|
--#define ENODEV 19
|
|
|
--#define ENOTDIR 20
|
|
|
--#define EISDIR 21
|
|
|
--#define EINVAL 22
|
|
|
--#define ENFILE 23
|
|
|
--#define EMFILE 24
|
|
|
--#define ENOTTY 25
|
|
|
--#define ETXTBSY 26
|
|
|
--#define EFBIG 27
|
|
|
--#define ENOSPC 28
|
|
|
--#define ESPIPE 29
|
|
|
--#define EROFS 30
|
|
|
--#define EMLINK 31
|
|
|
--#define EPIPE 32
|
|
|
--#define EDOM 33
|
|
|
--#define ERANGE 34
|
|
|
--#define EDEADLK 35
|
|
|
--#define ENAMETOOLONG 36
|
|
|
--#define ENOLCK 37
|
|
|
--#define ENOSYS 38
|
|
|
--#define ENOTEMPTY 39
|
|
|
--#define ELOOP 40
|
|
|
--#define EWOULDBLOCK EAGAIN
|
|
|
--#define ENOMSG 42
|
|
|
--#define EIDRM 43
|
|
|
--#define ECHRNG 44
|
|
|
--#define EL2NSYNC 45
|
|
|
--#define EL3HLT 46
|
|
|
--#define EL3RST 47
|
|
|
--#define ELNRNG 48
|
|
|
--#define EUNATCH 49
|
|
|
--#define ENOCSI 50
|
|
|
--#define EL2HLT 51
|
|
|
--#define EBADE 52
|
|
|
--#define EBADR 53
|
|
|
--#define EXFULL 54
|
|
|
--#define ENOANO 55
|
|
|
--#define EBADRQC 56
|
|
|
--#define EBADSLT 57
|
|
|
--#define EDEADLOCK EDEADLK
|
|
|
--#define EBFONT 59
|
|
|
--#define ENOSTR 60
|
|
|
--#define ENODATA 61
|
|
|
--#define ETIME 62
|
|
|
--#define ENOSR 63
|
|
|
--#define ENONET 64
|
|
|
--#define ENOPKG 65
|
|
|
--#define EREMOTE 66
|
|
|
--#define ENOLINK 67
|
|
|
--#define EADV 68
|
|
|
--#define ESRMNT 69
|
|
|
--#define ECOMM 70
|
|
|
--#define EPROTO 71
|
|
|
--#define EMULTIHOP 72
|
|
|
--#define EDOTDOT 73
|
|
|
--#define EBADMSG 74
|
|
|
--#define EOVERFLOW 75
|
|
|
--#define ENOTUNIQ 76
|
|
|
--#define EBADFD 77
|
|
|
--#define EREMCHG 78
|
|
|
--#define ELIBACC 79
|
|
|
--#define ELIBBAD 80
|
|
|
--#define ELIBSCN 81
|
|
|
--#define ELIBMAX 82
|
|
|
--#define ELIBEXEC 83
|
|
|
--#define EILSEQ 84
|
|
|
--#define ERESTART 85
|
|
|
--#define ESTRPIPE 86
|
|
|
--#define EUSERS 87
|
|
|
--#define ENOTSOCK 88
|
|
|
--#define EDESTADDRREQ 89
|
|
|
--#define EMSGSIZE 90
|
|
|
--#define EPROTOTYPE 91
|
|
|
--#define ENOPROTOOPT 92
|
|
|
--#define EPROTONOSUPPORT 93
|
|
|
--#define ESOCKTNOSUPPORT 94
|
|
|
--#define EOPNOTSUPP 95
|
|
|
--#define ENOTSUP EOPNOTSUPP
|
|
|
--#define EPFNOSUPPORT 96
|
|
|
--#define EAFNOSUPPORT 97
|
|
|
--#define EADDRINUSE 98
|
|
|
--#define EADDRNOTAVAIL 99
|
|
|
--#define ENETDOWN 100
|
|
|
--#define ENETUNREACH 101
|
|
|
--#define ENETRESET 102
|
|
|
--#define ECONNABORTED 103
|
|
|
--#define ECONNRESET 104
|
|
|
--#define ENOBUFS 105
|
|
|
--#define EISCONN 106
|
|
|
--#define ENOTCONN 107
|
|
|
--#define ESHUTDOWN 108
|
|
|
--#define ETOOMANYREFS 109
|
|
|
--#define ETIMEDOUT 110
|
|
|
--#define ECONNREFUSED 111
|
|
|
--#define EHOSTDOWN 112
|
|
|
--#define EHOSTUNREACH 113
|
|
|
--#define EALREADY 114
|
|
|
--#define EINPROGRESS 115
|
|
|
--#define ESTALE 116
|
|
|
--#define EUCLEAN 117
|
|
|
--#define ENOTNAM 118
|
|
|
--#define ENAVAIL 119
|
|
|
--#define EISNAM 120
|
|
|
--#define EREMOTEIO 121
|
|
|
--#define EDQUOT 122
|
|
|
--#define ENOMEDIUM 123
|
|
|
--#define EMEDIUMTYPE 124
|
|
|
--#define ECANCELED 125
|
|
|
--#define ENOKEY 126
|
|
|
--#define EKEYEXPIRED 127
|
|
|
--#define EKEYREVOKED 128
|
|
|
--#define EKEYREJECTED 129
|
|
|
--#define EOWNERDEAD 130
|
|
|
--#define ENOTRECOVERABLE 131
|
|
|
--#define ERFKILL 132
|
|
|
--#define EHWPOISON 133
|
|
|
---- a/arch/aarch64/bits/mman.h
|
|
|
-+++ b/arch/aarch64/bits/mman.h
|
|
|
-@@ -36,6 +36,7 @@
|
|
|
-
|
|
|
- #define MCL_CURRENT 1
|
|
|
- #define MCL_FUTURE 2
|
|
|
-+#define MCL_ONFAULT 4
|
|
|
-
|
|
|
- #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
- #define MADV_NORMAL 0
|
|
|
---- a/arch/aarch64/bits/statfs.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,7 +0,0 @@
|
|
|
--struct statfs {
|
|
|
-- unsigned long f_type, f_bsize;
|
|
|
-- fsblkcnt_t f_blocks, f_bfree, f_bavail;
|
|
|
-- fsfilcnt_t f_files, f_ffree;
|
|
|
-- fsid_t f_fsid;
|
|
|
-- unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
|
|
|
--};
|
|
|
---- a/arch/aarch64/bits/stdarg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,4 +0,0 @@
|
|
|
--#define va_start(v,l) __builtin_va_start(v,l)
|
|
|
--#define va_end(v) __builtin_va_end(v)
|
|
|
--#define va_arg(v,l) __builtin_va_arg(v,l)
|
|
|
--#define va_copy(d,s) __builtin_va_copy(d,s)
|
|
|
---- a/arch/aarch64/bits/syscall.h
|
|
|
-+++ b/arch/aarch64/bits/syscall.h
|
|
|
-@@ -265,6 +265,9 @@
|
|
|
- #define __NR_memfd_create 279
|
|
|
- #define __NR_bpf 280
|
|
|
- #define __NR_execveat 281
|
|
|
-+#define __NR_userfaultfd 282
|
|
|
-+#define __NR_membarrier 283
|
|
|
-+#define __NR_mlock2 284
|
|
|
-
|
|
|
- #define SYS_io_setup __NR_io_setup
|
|
|
- #define SYS_io_destroy __NR_io_destroy
|
|
|
-@@ -533,3 +536,6 @@
|
|
|
- #define SYS_memfd_create __NR_memfd_create
|
|
|
- #define SYS_bpf __NR_bpf
|
|
|
- #define SYS_execveat __NR_execveat
|
|
|
-+#define SYS_userfaultfd __NR_userfaultfd
|
|
|
-+#define SYS_membarrier __NR_membarrier
|
|
|
-+#define SYS_mlock2 __NR_mlock2
|
|
|
---- a/arch/aarch64/bits/termios.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,160 +0,0 @@
|
|
|
--struct termios
|
|
|
--{
|
|
|
-- tcflag_t c_iflag;
|
|
|
-- tcflag_t c_oflag;
|
|
|
-- tcflag_t c_cflag;
|
|
|
-- tcflag_t c_lflag;
|
|
|
-- cc_t c_line;
|
|
|
-- cc_t c_cc[NCCS];
|
|
|
-- speed_t __c_ispeed;
|
|
|
-- speed_t __c_ospeed;
|
|
|
--};
|
|
|
--
|
|
|
--#define VINTR 0
|
|
|
--#define VQUIT 1
|
|
|
--#define VERASE 2
|
|
|
--#define VKILL 3
|
|
|
--#define VEOF 4
|
|
|
--#define VTIME 5
|
|
|
--#define VMIN 6
|
|
|
--#define VSWTC 7
|
|
|
--#define VSTART 8
|
|
|
--#define VSTOP 9
|
|
|
--#define VSUSP 10
|
|
|
--#define VEOL 11
|
|
|
--#define VREPRINT 12
|
|
|
--#define VDISCARD 13
|
|
|
--#define VWERASE 14
|
|
|
--#define VLNEXT 15
|
|
|
--#define VEOL2 16
|
|
|
--
|
|
|
--#define IGNBRK 0000001
|
|
|
--#define BRKINT 0000002
|
|
|
--#define IGNPAR 0000004
|
|
|
--#define PARMRK 0000010
|
|
|
--#define INPCK 0000020
|
|
|
--#define ISTRIP 0000040
|
|
|
--#define INLCR 0000100
|
|
|
--#define IGNCR 0000200
|
|
|
--#define ICRNL 0000400
|
|
|
--#define IUCLC 0001000
|
|
|
--#define IXON 0002000
|
|
|
--#define IXANY 0004000
|
|
|
--#define IXOFF 0010000
|
|
|
--#define IMAXBEL 0020000
|
|
|
--#define IUTF8 0040000
|
|
|
--
|
|
|
--#define OPOST 0000001
|
|
|
--#define OLCUC 0000002
|
|
|
--#define ONLCR 0000004
|
|
|
--#define OCRNL 0000010
|
|
|
--#define ONOCR 0000020
|
|
|
--#define ONLRET 0000040
|
|
|
--#define OFILL 0000100
|
|
|
--#define OFDEL 0000200
|
|
|
--#define NLDLY 0000400
|
|
|
--#define NL0 0000000
|
|
|
--#define NL1 0000400
|
|
|
--#define CRDLY 0003000
|
|
|
--#define CR0 0000000
|
|
|
--#define CR1 0001000
|
|
|
--#define CR2 0002000
|
|
|
--#define CR3 0003000
|
|
|
--#define TABDLY 0014000
|
|
|
--#define TAB0 0000000
|
|
|
--#define TAB1 0004000
|
|
|
--#define TAB2 0010000
|
|
|
--#define TAB3 0014000
|
|
|
--#define BSDLY 0020000
|
|
|
--#define BS0 0000000
|
|
|
--#define BS1 0020000
|
|
|
--#define FFDLY 0100000
|
|
|
--#define FF0 0000000
|
|
|
--#define FF1 0100000
|
|
|
--
|
|
|
--#define VTDLY 0040000
|
|
|
--#define VT0 0000000
|
|
|
--#define VT1 0040000
|
|
|
--
|
|
|
--#define B0 0000000
|
|
|
--#define B50 0000001
|
|
|
--#define B75 0000002
|
|
|
--#define B110 0000003
|
|
|
--#define B134 0000004
|
|
|
--#define B150 0000005
|
|
|
--#define B200 0000006
|
|
|
--#define B300 0000007
|
|
|
--#define B600 0000010
|
|
|
--#define B1200 0000011
|
|
|
--#define B1800 0000012
|
|
|
--#define B2400 0000013
|
|
|
--#define B4800 0000014
|
|
|
--#define B9600 0000015
|
|
|
--#define B19200 0000016
|
|
|
--#define B38400 0000017
|
|
|
--
|
|
|
--#define B57600 0010001
|
|
|
--#define B115200 0010002
|
|
|
--#define B230400 0010003
|
|
|
--#define B460800 0010004
|
|
|
--#define B500000 0010005
|
|
|
--#define B576000 0010006
|
|
|
--#define B921600 0010007
|
|
|
--#define B1000000 0010010
|
|
|
--#define B1152000 0010011
|
|
|
--#define B1500000 0010012
|
|
|
--#define B2000000 0010013
|
|
|
--#define B2500000 0010014
|
|
|
--#define B3000000 0010015
|
|
|
--#define B3500000 0010016
|
|
|
--#define B4000000 0010017
|
|
|
--
|
|
|
--#define CBAUD 0010017
|
|
|
--
|
|
|
--#define CSIZE 0000060
|
|
|
--#define CS5 0000000
|
|
|
--#define CS6 0000020
|
|
|
--#define CS7 0000040
|
|
|
--#define CS8 0000060
|
|
|
--#define CSTOPB 0000100
|
|
|
--#define CREAD 0000200
|
|
|
--#define PARENB 0000400
|
|
|
--#define PARODD 0001000
|
|
|
--#define HUPCL 0002000
|
|
|
--#define CLOCAL 0004000
|
|
|
--
|
|
|
--#define ISIG 0000001
|
|
|
--#define ICANON 0000002
|
|
|
--#define ECHO 0000010
|
|
|
--#define ECHOE 0000020
|
|
|
--#define ECHOK 0000040
|
|
|
--#define ECHONL 0000100
|
|
|
--#define NOFLSH 0000200
|
|
|
--#define TOSTOP 0000400
|
|
|
--#define IEXTEN 0100000
|
|
|
--
|
|
|
--#define ECHOCTL 0001000
|
|
|
--#define ECHOPRT 0002000
|
|
|
--#define ECHOKE 0004000
|
|
|
--#define FLUSHO 0010000
|
|
|
--#define PENDIN 0040000
|
|
|
--
|
|
|
--#define TCOOFF 0
|
|
|
--#define TCOON 1
|
|
|
--#define TCIOFF 2
|
|
|
--#define TCION 3
|
|
|
--
|
|
|
--#define TCIFLUSH 0
|
|
|
--#define TCOFLUSH 1
|
|
|
--#define TCIOFLUSH 2
|
|
|
--
|
|
|
--#define TCSANOW 0
|
|
|
--#define TCSADRAIN 1
|
|
|
--#define TCSAFLUSH 2
|
|
|
--
|
|
|
--#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
--#define CBAUDEX 0010000
|
|
|
--#define CRTSCTS 020000000000
|
|
|
--#define EXTPROC 0200000
|
|
|
--#define XTABS 0014000
|
|
|
--#endif
|
|
|
---- a/arch/aarch64/pthread_arch.h
|
|
|
-+++ b/arch/aarch64/pthread_arch.h
|
|
|
-@@ -8,4 +8,4 @@ static inline struct pthread *__pthread_
|
|
|
- #define TLS_ABOVE_TP
|
|
|
- #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 16)
|
|
|
-
|
|
|
--#define CANCEL_REG_IP 33
|
|
|
-+#define MC_PC pc
|
|
|
---- a/arch/arm/atomic.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,261 +0,0 @@
|
|
|
--#ifndef _INTERNAL_ATOMIC_H
|
|
|
--#define _INTERNAL_ATOMIC_H
|
|
|
--
|
|
|
--#include <stdint.h>
|
|
|
--
|
|
|
--static inline int a_ctz_l(unsigned long x)
|
|
|
--{
|
|
|
-- static const char debruijn32[32] = {
|
|
|
-- 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
|
|
|
-- 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
|
|
|
-- };
|
|
|
-- return debruijn32[(x&-x)*0x076be629 >> 27];
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_ctz_64(uint64_t x)
|
|
|
--{
|
|
|
-- uint32_t y = x;
|
|
|
-- if (!y) {
|
|
|
-- y = x>>32;
|
|
|
-- return 32 + a_ctz_l(y);
|
|
|
-- }
|
|
|
-- return a_ctz_l(y);
|
|
|
--}
|
|
|
--
|
|
|
--#if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
|
|
|
--
|
|
|
--static inline void a_barrier()
|
|
|
--{
|
|
|
-- __asm__ __volatile__("dmb ish");
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_cas(volatile int *p, int t, int s)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldrex %0,%3\n"
|
|
|
-- " cmp %0,%1\n"
|
|
|
-- " bne 1f\n"
|
|
|
-- " strex %0,%2,%3\n"
|
|
|
-- " cmp %0, #0\n"
|
|
|
-- " bne 1b\n"
|
|
|
-- " mov %0, %1\n"
|
|
|
-- "1: dmb ish\n"
|
|
|
-- : "=&r"(old)
|
|
|
-- : "r"(t), "r"(s), "Q"(*p)
|
|
|
-- : "memory", "cc" );
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_swap(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old, tmp;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldrex %0,%3\n"
|
|
|
-- " strex %1,%2,%3\n"
|
|
|
-- " cmp %1, #0\n"
|
|
|
-- " bne 1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(old), "=&r"(tmp)
|
|
|
-- : "r"(v), "Q"(*x)
|
|
|
-- : "memory", "cc" );
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_fetch_add(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old, tmp;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldrex %0,%3\n"
|
|
|
-- " add %0,%0,%2\n"
|
|
|
-- " strex %1,%0,%3\n"
|
|
|
-- " cmp %1, #0\n"
|
|
|
-- " bne 1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(old), "=&r"(tmp)
|
|
|
-- : "r"(v), "Q"(*x)
|
|
|
-- : "memory", "cc" );
|
|
|
-- return old-v;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_inc(volatile int *x)
|
|
|
--{
|
|
|
-- int tmp, tmp2;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldrex %0,%2\n"
|
|
|
-- " add %0,%0,#1\n"
|
|
|
-- " strex %1,%0,%2\n"
|
|
|
-- " cmp %1, #0\n"
|
|
|
-- " bne 1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(tmp), "=&r"(tmp2)
|
|
|
-- : "Q"(*x)
|
|
|
-- : "memory", "cc" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_dec(volatile int *x)
|
|
|
--{
|
|
|
-- int tmp, tmp2;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldrex %0,%2\n"
|
|
|
-- " sub %0,%0,#1\n"
|
|
|
-- " strex %1,%0,%2\n"
|
|
|
-- " cmp %1, #0\n"
|
|
|
-- " bne 1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(tmp), "=&r"(tmp2)
|
|
|
-- : "Q"(*x)
|
|
|
-- : "memory", "cc" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int tmp, tmp2;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldrex %0,%3\n"
|
|
|
-- " and %0,%0,%2\n"
|
|
|
-- " strex %1,%0,%3\n"
|
|
|
-- " cmp %1, #0\n"
|
|
|
-- " bne 1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(tmp), "=&r"(tmp2)
|
|
|
-- : "r"(v), "Q"(*x)
|
|
|
-- : "memory", "cc" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int tmp, tmp2;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- "1: ldrex %0,%3\n"
|
|
|
-- " orr %0,%0,%2\n"
|
|
|
-- " strex %1,%0,%3\n"
|
|
|
-- " cmp %1, #0\n"
|
|
|
-- " bne 1b\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=&r"(tmp), "=&r"(tmp2)
|
|
|
-- : "r"(v), "Q"(*x)
|
|
|
-- : "memory", "cc" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_store(volatile int *p, int x)
|
|
|
--{
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " dmb ish\n"
|
|
|
-- " str %1,%0\n"
|
|
|
-- " dmb ish\n"
|
|
|
-- : "=m"(*p)
|
|
|
-- : "r"(x)
|
|
|
-- : "memory", "cc" );
|
|
|
--}
|
|
|
--
|
|
|
--#else
|
|
|
--
|
|
|
--int __a_cas(int, int, volatile int *) __attribute__((__visibility__("hidden")));
|
|
|
--#define __k_cas __a_cas
|
|
|
--
|
|
|
--static inline void a_barrier()
|
|
|
--{
|
|
|
-- __asm__ __volatile__("bl __a_barrier"
|
|
|
-- : : : "memory", "cc", "ip", "lr" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_cas(volatile int *p, int t, int s)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- for (;;) {
|
|
|
-- if (!__k_cas(t, s, p))
|
|
|
-- return t;
|
|
|
-- if ((old=*p) != t)
|
|
|
-- return old;
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_swap(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *x;
|
|
|
-- while (__k_cas(old, v, x));
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_fetch_add(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *x;
|
|
|
-- while (__k_cas(old, old+v, x));
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_inc(volatile int *x)
|
|
|
--{
|
|
|
-- a_fetch_add(x, 1);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_dec(volatile int *x)
|
|
|
--{
|
|
|
-- a_fetch_add(x, -1);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_store(volatile int *p, int x)
|
|
|
--{
|
|
|
-- a_barrier();
|
|
|
-- *p = x;
|
|
|
-- a_barrier();
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and(volatile int *p, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *p;
|
|
|
-- while (__k_cas(old, old&v, p));
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or(volatile int *p, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *p;
|
|
|
-- while (__k_cas(old, old|v, p));
|
|
|
--}
|
|
|
--
|
|
|
--#endif
|
|
|
--
|
|
|
--static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
--{
|
|
|
-- return (void *)a_cas(p, (int)t, (int)s);
|
|
|
--}
|
|
|
--
|
|
|
--#define a_spin a_barrier
|
|
|
--
|
|
|
--static inline void a_crash()
|
|
|
--{
|
|
|
-- *(volatile char *)0=0;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_l(volatile void *p, long v)
|
|
|
--{
|
|
|
-- a_or(p, v);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-- a_and((int *)p, u.r[0]);
|
|
|
-- a_and((int *)p+1, u.r[1]);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-- a_or((int *)p, u.r[0]);
|
|
|
-- a_or((int *)p+1, u.r[1]);
|
|
|
--}
|
|
|
--
|
|
|
--#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/arm/atomic_arch.h
|
|
|
-@@ -0,0 +1,76 @@
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+extern const void *__arm_atomics[3]; /* gettp, cas, barrier */
|
|
|
-+
|
|
|
-+#if ((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6ZK__) && !__thumb__) \
|
|
|
-+ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
|
|
|
-+
|
|
|
-+#define a_ll a_ll
|
|
|
-+static inline int a_ll(volatile int *p)
|
|
|
-+{
|
|
|
-+ int v;
|
|
|
-+ __asm__ __volatile__ ("ldrex %0, %1" : "=r"(v) : "Q"(*p));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_sc a_sc
|
|
|
-+static inline int a_sc(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int r;
|
|
|
-+ __asm__ __volatile__ ("strex %0,%1,%2" : "=&r"(r) : "r"(v), "Q"(*p) : "memory");
|
|
|
-+ return !r;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
|
|
|
-+
|
|
|
-+#define a_barrier a_barrier
|
|
|
-+static inline void a_barrier()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__ ("dmb ish" : : : "memory");
|
|
|
-+}
|
|
|
-+
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#define a_pre_llsc a_barrier
|
|
|
-+#define a_post_llsc a_barrier
|
|
|
-+
|
|
|
-+#else
|
|
|
-+
|
|
|
-+#define a_cas a_cas
|
|
|
-+static inline int a_cas(volatile int *p, int t, int s)
|
|
|
-+{
|
|
|
-+ for (;;) {
|
|
|
-+ register int r0 __asm__("r0") = t;
|
|
|
-+ register int r1 __asm__("r1") = s;
|
|
|
-+ register volatile int *r2 __asm__("r2") = p;
|
|
|
-+ int old;
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ "bl __a_cas"
|
|
|
-+ : "+r"(r0) : "r"(r1), "r"(r2)
|
|
|
-+ : "memory", "r3", "lr", "ip", "cc" );
|
|
|
-+ if (!r0) return t;
|
|
|
-+ if ((old=*p)!=t) return old;
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_barrier
|
|
|
-+#define a_barrier a_barrier
|
|
|
-+static inline void a_barrier()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__("bl __a_barrier"
|
|
|
-+ : : : "memory", "cc", "ip", "lr" );
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#define a_crash a_crash
|
|
|
-+static inline void a_crash()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+#ifndef __thumb__
|
|
|
-+ ".word 0xe7f000f0"
|
|
|
-+#else
|
|
|
-+ ".short 0xdeff"
|
|
|
-+#endif
|
|
|
-+ : : : "memory");
|
|
|
-+}
|
|
|
---- a/arch/arm/bits/errno.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,134 +0,0 @@
|
|
|
--#define EPERM 1
|
|
|
--#define ENOENT 2
|
|
|
--#define ESRCH 3
|
|
|
--#define EINTR 4
|
|
|
--#define EIO 5
|
|
|
--#define ENXIO 6
|
|
|
--#define E2BIG 7
|
|
|
--#define ENOEXEC 8
|
|
|
--#define EBADF 9
|
|
|
--#define ECHILD 10
|
|
|
--#define EAGAIN 11
|
|
|
--#define ENOMEM 12
|
|
|
--#define EACCES 13
|
|
|
--#define EFAULT 14
|
|
|
--#define ENOTBLK 15
|
|
|
--#define EBUSY 16
|
|
|
--#define EEXIST 17
|
|
|
--#define EXDEV 18
|
|
|
--#define ENODEV 19
|
|
|
--#define ENOTDIR 20
|
|
|
--#define EISDIR 21
|
|
|
--#define EINVAL 22
|
|
|
--#define ENFILE 23
|
|
|
--#define EMFILE 24
|
|
|
--#define ENOTTY 25
|
|
|
--#define ETXTBSY 26
|
|
|
--#define EFBIG 27
|
|
|
--#define ENOSPC 28
|
|
|
--#define ESPIPE 29
|
|
|
--#define EROFS 30
|
|
|
--#define EMLINK 31
|
|
|
--#define EPIPE 32
|
|
|
--#define EDOM 33
|
|
|
--#define ERANGE 34
|
|
|
--#define EDEADLK 35
|
|
|
--#define ENAMETOOLONG 36
|
|
|
--#define ENOLCK 37
|
|
|
--#define ENOSYS 38
|
|
|
--#define ENOTEMPTY 39
|
|
|
--#define ELOOP 40
|
|
|
--#define EWOULDBLOCK EAGAIN
|
|
|
--#define ENOMSG 42
|
|
|
--#define EIDRM 43
|
|
|
--#define ECHRNG 44
|
|
|
--#define EL2NSYNC 45
|
|
|
--#define EL3HLT 46
|
|
|
--#define EL3RST 47
|
|
|
--#define ELNRNG 48
|
|
|
--#define EUNATCH 49
|
|
|
--#define ENOCSI 50
|
|
|
--#define EL2HLT 51
|
|
|
--#define EBADE 52
|
|
|
--#define EBADR 53
|
|
|
--#define EXFULL 54
|
|
|
--#define ENOANO 55
|
|
|
--#define EBADRQC 56
|
|
|
--#define EBADSLT 57
|
|
|
--#define EDEADLOCK EDEADLK
|
|
|
--#define EBFONT 59
|
|
|
--#define ENOSTR 60
|
|
|
--#define ENODATA 61
|
|
|
--#define ETIME 62
|
|
|
--#define ENOSR 63
|
|
|
--#define ENONET 64
|
|
|
--#define ENOPKG 65
|
|
|
--#define EREMOTE 66
|
|
|
--#define ENOLINK 67
|
|
|
--#define EADV 68
|
|
|
--#define ESRMNT 69
|
|
|
--#define ECOMM 70
|
|
|
--#define EPROTO 71
|
|
|
--#define EMULTIHOP 72
|
|
|
--#define EDOTDOT 73
|
|
|
--#define EBADMSG 74
|
|
|
--#define EOVERFLOW 75
|
|
|
--#define ENOTUNIQ 76
|
|
|
--#define EBADFD 77
|
|
|
--#define EREMCHG 78
|
|
|
--#define ELIBACC 79
|
|
|
--#define ELIBBAD 80
|
|
|
--#define ELIBSCN 81
|
|
|
--#define ELIBMAX 82
|
|
|
--#define ELIBEXEC 83
|
|
|
--#define EILSEQ 84
|
|
|
--#define ERESTART 85
|
|
|
--#define ESTRPIPE 86
|
|
|
--#define EUSERS 87
|
|
|
--#define ENOTSOCK 88
|
|
|
--#define EDESTADDRREQ 89
|
|
|
--#define EMSGSIZE 90
|
|
|
--#define EPROTOTYPE 91
|
|
|
--#define ENOPROTOOPT 92
|
|
|
--#define EPROTONOSUPPORT 93
|
|
|
--#define ESOCKTNOSUPPORT 94
|
|
|
--#define EOPNOTSUPP 95
|
|
|
--#define ENOTSUP EOPNOTSUPP
|
|
|
--#define EPFNOSUPPORT 96
|
|
|
--#define EAFNOSUPPORT 97
|
|
|
--#define EADDRINUSE 98
|
|
|
--#define EADDRNOTAVAIL 99
|
|
|
--#define ENETDOWN 100
|
|
|
--#define ENETUNREACH 101
|
|
|
--#define ENETRESET 102
|
|
|
--#define ECONNABORTED 103
|
|
|
--#define ECONNRESET 104
|
|
|
--#define ENOBUFS 105
|
|
|
--#define EISCONN 106
|
|
|
--#define ENOTCONN 107
|
|
|
--#define ESHUTDOWN 108
|
|
|
--#define ETOOMANYREFS 109
|
|
|
--#define ETIMEDOUT 110
|
|
|
--#define ECONNREFUSED 111
|
|
|
--#define EHOSTDOWN 112
|
|
|
--#define EHOSTUNREACH 113
|
|
|
--#define EALREADY 114
|
|
|
--#define EINPROGRESS 115
|
|
|
--#define ESTALE 116
|
|
|
--#define EUCLEAN 117
|
|
|
--#define ENOTNAM 118
|
|
|
--#define ENAVAIL 119
|
|
|
--#define EISNAM 120
|
|
|
--#define EREMOTEIO 121
|
|
|
--#define EDQUOT 122
|
|
|
--#define ENOMEDIUM 123
|
|
|
--#define EMEDIUMTYPE 124
|
|
|
--#define ECANCELED 125
|
|
|
--#define ENOKEY 126
|
|
|
--#define EKEYEXPIRED 127
|
|
|
--#define EKEYREVOKED 128
|
|
|
--#define EKEYREJECTED 129
|
|
|
--#define EOWNERDEAD 130
|
|
|
--#define ENOTRECOVERABLE 131
|
|
|
--#define ERFKILL 132
|
|
|
--#define EHWPOISON 133
|
|
|
---- a/arch/arm/bits/ioctl.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,197 +0,0 @@
|
|
|
--#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
|
|
|
--#define _IOC_NONE 0U
|
|
|
--#define _IOC_WRITE 1U
|
|
|
--#define _IOC_READ 2U
|
|
|
--
|
|
|
--#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
|
|
|
--#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
|
|
|
--#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
|
|
|
--#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
|
|
|
--
|
|
|
--#define TCGETS 0x5401
|
|
|
--#define TCSETS 0x5402
|
|
|
--#define TCSETSW 0x5403
|
|
|
--#define TCSETSF 0x5404
|
|
|
--#define TCGETA 0x5405
|
|
|
--#define TCSETA 0x5406
|
|
|
--#define TCSETAW 0x5407
|
|
|
--#define TCSETAF 0x5408
|
|
|
--#define TCSBRK 0x5409
|
|
|
--#define TCXONC 0x540A
|
|
|
--#define TCFLSH 0x540B
|
|
|
--#define TIOCEXCL 0x540C
|
|
|
--#define TIOCNXCL 0x540D
|
|
|
--#define TIOCSCTTY 0x540E
|
|
|
--#define TIOCGPGRP 0x540F
|
|
|
--#define TIOCSPGRP 0x5410
|
|
|
--#define TIOCOUTQ 0x5411
|
|
|
--#define TIOCSTI 0x5412
|
|
|
--#define TIOCGWINSZ 0x5413
|
|
|
--#define TIOCSWINSZ 0x5414
|
|
|
--#define TIOCMGET 0x5415
|
|
|
--#define TIOCMBIS 0x5416
|
|
|
--#define TIOCMBIC 0x5417
|
|
|
--#define TIOCMSET 0x5418
|
|
|
--#define TIOCGSOFTCAR 0x5419
|
|
|
--#define TIOCSSOFTCAR 0x541A
|
|
|
--#define FIONREAD 0x541B
|
|
|
--#define TIOCINQ FIONREAD
|
|
|
--#define TIOCLINUX 0x541C
|
|
|
--#define TIOCCONS 0x541D
|
|
|
--#define TIOCGSERIAL 0x541E
|
|
|
--#define TIOCSSERIAL 0x541F
|
|
|
--#define TIOCPKT 0x5420
|
|
|
--#define FIONBIO 0x5421
|
|
|
--#define TIOCNOTTY 0x5422
|
|
|
--#define TIOCSETD 0x5423
|
|
|
--#define TIOCGETD 0x5424
|
|
|
--#define TCSBRKP 0x5425
|
|
|
--#define TIOCTTYGSTRUCT 0x5426
|
|
|
--#define TIOCSBRK 0x5427
|
|
|
--#define TIOCCBRK 0x5428
|
|
|
--#define TIOCGSID 0x5429
|
|
|
--#define TIOCGPTN 0x80045430
|
|
|
--#define TIOCSPTLCK 0x40045431
|
|
|
--#define TCGETX 0x5432
|
|
|
--#define TCSETX 0x5433
|
|
|
--#define TCSETXF 0x5434
|
|
|
--#define TCSETXW 0x5435
|
|
|
--
|
|
|
--#define FIONCLEX 0x5450
|
|
|
--#define FIOCLEX 0x5451
|
|
|
--#define FIOASYNC 0x5452
|
|
|
--#define TIOCSERCONFIG 0x5453
|
|
|
--#define TIOCSERGWILD 0x5454
|
|
|
--#define TIOCSERSWILD 0x5455
|
|
|
--#define TIOCGLCKTRMIOS 0x5456
|
|
|
--#define TIOCSLCKTRMIOS 0x5457
|
|
|
--#define TIOCSERGSTRUCT 0x5458
|
|
|
--#define TIOCSERGETLSR 0x5459
|
|
|
--#define TIOCSERGETMULTI 0x545A
|
|
|
--#define TIOCSERSETMULTI 0x545B
|
|
|
--
|
|
|
--#define TIOCMIWAIT 0x545C
|
|
|
--#define TIOCGICOUNT 0x545D
|
|
|
--#define TIOCGHAYESESP 0x545E
|
|
|
--#define TIOCSHAYESESP 0x545F
|
|
|
--#define FIOQSIZE 0x5460
|
|
|
--
|
|
|
--#define TIOCPKT_DATA 0
|
|
|
--#define TIOCPKT_FLUSHREAD 1
|
|
|
--#define TIOCPKT_FLUSHWRITE 2
|
|
|
--#define TIOCPKT_STOP 4
|
|
|
--#define TIOCPKT_START 8
|
|
|
--#define TIOCPKT_NOSTOP 16
|
|
|
--#define TIOCPKT_DOSTOP 32
|
|
|
--#define TIOCPKT_IOCTL 64
|
|
|
--
|
|
|
--#define TIOCSER_TEMT 0x01
|
|
|
--
|
|
|
--struct winsize {
|
|
|
-- unsigned short ws_row;
|
|
|
-- unsigned short ws_col;
|
|
|
-- unsigned short ws_xpixel;
|
|
|
-- unsigned short ws_ypixel;
|
|
|
--};
|
|
|
--
|
|
|
--#define TIOCM_LE 0x001
|
|
|
--#define TIOCM_DTR 0x002
|
|
|
--#define TIOCM_RTS 0x004
|
|
|
--#define TIOCM_ST 0x008
|
|
|
--#define TIOCM_SR 0x010
|
|
|
--#define TIOCM_CTS 0x020
|
|
|
--#define TIOCM_CAR 0x040
|
|
|
--#define TIOCM_RNG 0x080
|
|
|
--#define TIOCM_DSR 0x100
|
|
|
--#define TIOCM_CD TIOCM_CAR
|
|
|
--#define TIOCM_RI TIOCM_RNG
|
|
|
--#define TIOCM_OUT1 0x2000
|
|
|
--#define TIOCM_OUT2 0x4000
|
|
|
--#define TIOCM_LOOP 0x8000
|
|
|
--#define TIOCM_MODEM_BITS TIOCM_OUT2
|
|
|
--
|
|
|
--#define N_TTY 0
|
|
|
--#define N_SLIP 1
|
|
|
--#define N_MOUSE 2
|
|
|
--#define N_PPP 3
|
|
|
--#define N_STRIP 4
|
|
|
--#define N_AX25 5
|
|
|
--#define N_X25 6
|
|
|
--#define N_6PACK 7
|
|
|
--#define N_MASC 8
|
|
|
--#define N_R3964 9
|
|
|
--#define N_PROFIBUS_FDL 10
|
|
|
--#define N_IRDA 11
|
|
|
--#define N_SMSBLOCK 12
|
|
|
--#define N_HDLC 13
|
|
|
--#define N_SYNC_PPP 14
|
|
|
--#define N_HCI 15
|
|
|
--
|
|
|
--#define FIOSETOWN 0x8901
|
|
|
--#define SIOCSPGRP 0x8902
|
|
|
--#define FIOGETOWN 0x8903
|
|
|
--#define SIOCGPGRP 0x8904
|
|
|
--#define SIOCATMARK 0x8905
|
|
|
--#define SIOCGSTAMP 0x8906
|
|
|
--
|
|
|
--#define SIOCADDRT 0x890B
|
|
|
--#define SIOCDELRT 0x890C
|
|
|
--#define SIOCRTMSG 0x890D
|
|
|
--
|
|
|
--#define SIOCGIFNAME 0x8910
|
|
|
--#define SIOCSIFLINK 0x8911
|
|
|
--#define SIOCGIFCONF 0x8912
|
|
|
--#define SIOCGIFFLAGS 0x8913
|
|
|
--#define SIOCSIFFLAGS 0x8914
|
|
|
--#define SIOCGIFADDR 0x8915
|
|
|
--#define SIOCSIFADDR 0x8916
|
|
|
--#define SIOCGIFDSTADDR 0x8917
|
|
|
--#define SIOCSIFDSTADDR 0x8918
|
|
|
--#define SIOCGIFBRDADDR 0x8919
|
|
|
--#define SIOCSIFBRDADDR 0x891a
|
|
|
--#define SIOCGIFNETMASK 0x891b
|
|
|
--#define SIOCSIFNETMASK 0x891c
|
|
|
--#define SIOCGIFMETRIC 0x891d
|
|
|
--#define SIOCSIFMETRIC 0x891e
|
|
|
--#define SIOCGIFMEM 0x891f
|
|
|
--#define SIOCSIFMEM 0x8920
|
|
|
--#define SIOCGIFMTU 0x8921
|
|
|
--#define SIOCSIFMTU 0x8922
|
|
|
--#define SIOCSIFHWADDR 0x8924
|
|
|
--#define SIOCGIFENCAP 0x8925
|
|
|
--#define SIOCSIFENCAP 0x8926
|
|
|
--#define SIOCGIFHWADDR 0x8927
|
|
|
--#define SIOCGIFSLAVE 0x8929
|
|
|
--#define SIOCSIFSLAVE 0x8930
|
|
|
--#define SIOCADDMULTI 0x8931
|
|
|
--#define SIOCDELMULTI 0x8932
|
|
|
--#define SIOCGIFINDEX 0x8933
|
|
|
--#define SIOGIFINDEX SIOCGIFINDEX
|
|
|
--#define SIOCSIFPFLAGS 0x8934
|
|
|
--#define SIOCGIFPFLAGS 0x8935
|
|
|
--#define SIOCDIFADDR 0x8936
|
|
|
--#define SIOCSIFHWBROADCAST 0x8937
|
|
|
--#define SIOCGIFCOUNT 0x8938
|
|
|
--
|
|
|
--#define SIOCGIFBR 0x8940
|
|
|
--#define SIOCSIFBR 0x8941
|
|
|
--
|
|
|
--#define SIOCGIFTXQLEN 0x8942
|
|
|
--#define SIOCSIFTXQLEN 0x8943
|
|
|
--
|
|
|
--#define SIOCDARP 0x8953
|
|
|
--#define SIOCGARP 0x8954
|
|
|
--#define SIOCSARP 0x8955
|
|
|
--
|
|
|
--#define SIOCDRARP 0x8960
|
|
|
--#define SIOCGRARP 0x8961
|
|
|
--#define SIOCSRARP 0x8962
|
|
|
--
|
|
|
--#define SIOCGIFMAP 0x8970
|
|
|
--#define SIOCSIFMAP 0x8971
|
|
|
--
|
|
|
--#define SIOCADDDLCI 0x8980
|
|
|
--#define SIOCDELDLCI 0x8981
|
|
|
--
|
|
|
--#define SIOCDEVPRIVATE 0x89F0
|
|
|
--#define SIOCPROTOPRIVATE 0x89E0
|
|
|
---- a/arch/arm/bits/ipc.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,14 +0,0 @@
|
|
|
--struct ipc_perm
|
|
|
--{
|
|
|
-- key_t __ipc_perm_key;
|
|
|
-- uid_t uid;
|
|
|
-- gid_t gid;
|
|
|
-- uid_t cuid;
|
|
|
-- gid_t cgid;
|
|
|
-- mode_t mode;
|
|
|
-- int __ipc_perm_seq;
|
|
|
-- long __pad1;
|
|
|
-- long __pad2;
|
|
|
--};
|
|
|
--
|
|
|
--#define IPC_64 0x100
|
|
|
---- a/arch/arm/bits/mman.h
|
|
|
-+++ b/arch/arm/bits/mman.h
|
|
|
-@@ -37,6 +37,7 @@
|
|
|
-
|
|
|
- #define MCL_CURRENT 1
|
|
|
- #define MCL_FUTURE 2
|
|
|
-+#define MCL_ONFAULT 4
|
|
|
-
|
|
|
- #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
- #define MADV_NORMAL 0
|
|
|
---- a/arch/arm/bits/msg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,16 +0,0 @@
|
|
|
--struct msqid_ds
|
|
|
--{
|
|
|
-- struct ipc_perm msg_perm;
|
|
|
-- time_t msg_stime;
|
|
|
-- int __unused1;
|
|
|
-- time_t msg_rtime;
|
|
|
-- int __unused2;
|
|
|
-- time_t msg_ctime;
|
|
|
-- int __unused3;
|
|
|
-- unsigned long msg_cbytes;
|
|
|
-- msgqnum_t msg_qnum;
|
|
|
-- msglen_t msg_qbytes;
|
|
|
-- pid_t msg_lspid;
|
|
|
-- pid_t msg_lrpid;
|
|
|
-- unsigned long __unused[2];
|
|
|
--};
|
|
|
---- a/arch/arm/bits/sem.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,16 +0,0 @@
|
|
|
--struct semid_ds {
|
|
|
-- struct ipc_perm sem_perm;
|
|
|
-- time_t sem_otime;
|
|
|
-- time_t __unused1;
|
|
|
-- time_t sem_ctime;
|
|
|
-- time_t __unused2;
|
|
|
--#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
-- unsigned short sem_nsems;
|
|
|
-- char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
--#else
|
|
|
-- char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
-- unsigned short sem_nsems;
|
|
|
--#endif
|
|
|
-- time_t __unused3;
|
|
|
-- time_t __unused4;
|
|
|
--};
|
|
|
---- a/arch/arm/bits/shm.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,29 +0,0 @@
|
|
|
--#define SHMLBA 4096
|
|
|
--
|
|
|
--struct shmid_ds
|
|
|
--{
|
|
|
-- struct ipc_perm shm_perm;
|
|
|
-- size_t shm_segsz;
|
|
|
-- time_t shm_atime;
|
|
|
-- int __unused1;
|
|
|
-- time_t shm_dtime;
|
|
|
-- int __unused2;
|
|
|
-- time_t shm_ctime;
|
|
|
-- int __unused3;
|
|
|
-- pid_t shm_cpid;
|
|
|
-- pid_t shm_lpid;
|
|
|
-- unsigned long shm_nattch;
|
|
|
-- unsigned long __pad1;
|
|
|
-- unsigned long __pad2;
|
|
|
--};
|
|
|
--
|
|
|
--struct shminfo {
|
|
|
-- unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
|
|
|
--};
|
|
|
--
|
|
|
--struct shm_info {
|
|
|
-- int __used_ids;
|
|
|
-- unsigned long shm_tot, shm_rss, shm_swp;
|
|
|
-- unsigned long __swap_attempts, __swap_successes;
|
|
|
--};
|
|
|
--
|
|
|
---- a/arch/arm/bits/socket.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,17 +0,0 @@
|
|
|
--struct msghdr
|
|
|
--{
|
|
|
-- void *msg_name;
|
|
|
-- socklen_t msg_namelen;
|
|
|
-- struct iovec *msg_iov;
|
|
|
-- int msg_iovlen;
|
|
|
-- void *msg_control;
|
|
|
-- socklen_t msg_controllen;
|
|
|
-- int msg_flags;
|
|
|
--};
|
|
|
--
|
|
|
--struct cmsghdr
|
|
|
--{
|
|
|
-- socklen_t cmsg_len;
|
|
|
-- int cmsg_level;
|
|
|
-- int cmsg_type;
|
|
|
--};
|
|
|
---- a/arch/arm/bits/statfs.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,7 +0,0 @@
|
|
|
--struct statfs {
|
|
|
-- unsigned long f_type, f_bsize;
|
|
|
-- fsblkcnt_t f_blocks, f_bfree, f_bavail;
|
|
|
-- fsfilcnt_t f_files, f_ffree;
|
|
|
-- fsid_t f_fsid;
|
|
|
-- unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
|
|
|
--};
|
|
|
---- a/arch/arm/bits/stdarg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,4 +0,0 @@
|
|
|
--#define va_start(v,l) __builtin_va_start(v,l)
|
|
|
--#define va_end(v) __builtin_va_end(v)
|
|
|
--#define va_arg(v,l) __builtin_va_arg(v,l)
|
|
|
--#define va_copy(d,s) __builtin_va_copy(d,s)
|
|
|
---- a/arch/arm/bits/syscall.h
|
|
|
-+++ b/arch/arm/bits/syscall.h
|
|
|
-@@ -341,6 +341,9 @@
|
|
|
- #define __NR_memfd_create 385
|
|
|
- #define __NR_bpf 386
|
|
|
- #define __NR_execveat 387
|
|
|
-+#define __NR_userfaultfd 388
|
|
|
-+#define __NR_membarrier 389
|
|
|
-+#define __NR_mlock2 390
|
|
|
-
|
|
|
- #define __ARM_NR_breakpoint 0x0f0001
|
|
|
- #define __ARM_NR_cacheflush 0x0f0002
|
|
|
-@@ -693,3 +696,6 @@
|
|
|
- #define SYS_memfd_create 385
|
|
|
- #define SYS_bpf 386
|
|
|
- #define SYS_execveat 387
|
|
|
-+#define SYS_userfaultfd 388
|
|
|
-+#define SYS_membarrier 389
|
|
|
-+#define SYS_mlock2 390
|
|
|
---- a/arch/arm/bits/termios.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,160 +0,0 @@
|
|
|
--struct termios
|
|
|
--{
|
|
|
-- tcflag_t c_iflag;
|
|
|
-- tcflag_t c_oflag;
|
|
|
-- tcflag_t c_cflag;
|
|
|
-- tcflag_t c_lflag;
|
|
|
-- cc_t c_line;
|
|
|
-- cc_t c_cc[NCCS];
|
|
|
-- speed_t __c_ispeed;
|
|
|
-- speed_t __c_ospeed;
|
|
|
--};
|
|
|
--
|
|
|
--#define VINTR 0
|
|
|
--#define VQUIT 1
|
|
|
--#define VERASE 2
|
|
|
--#define VKILL 3
|
|
|
--#define VEOF 4
|
|
|
--#define VTIME 5
|
|
|
--#define VMIN 6
|
|
|
--#define VSWTC 7
|
|
|
--#define VSTART 8
|
|
|
--#define VSTOP 9
|
|
|
--#define VSUSP 10
|
|
|
--#define VEOL 11
|
|
|
--#define VREPRINT 12
|
|
|
--#define VDISCARD 13
|
|
|
--#define VWERASE 14
|
|
|
--#define VLNEXT 15
|
|
|
--#define VEOL2 16
|
|
|
--
|
|
|
--#define IGNBRK 0000001
|
|
|
--#define BRKINT 0000002
|
|
|
--#define IGNPAR 0000004
|
|
|
--#define PARMRK 0000010
|
|
|
--#define INPCK 0000020
|
|
|
--#define ISTRIP 0000040
|
|
|
--#define INLCR 0000100
|
|
|
--#define IGNCR 0000200
|
|
|
--#define ICRNL 0000400
|
|
|
--#define IUCLC 0001000
|
|
|
--#define IXON 0002000
|
|
|
--#define IXANY 0004000
|
|
|
--#define IXOFF 0010000
|
|
|
--#define IMAXBEL 0020000
|
|
|
--#define IUTF8 0040000
|
|
|
--
|
|
|
--#define OPOST 0000001
|
|
|
--#define OLCUC 0000002
|
|
|
--#define ONLCR 0000004
|
|
|
--#define OCRNL 0000010
|
|
|
--#define ONOCR 0000020
|
|
|
--#define ONLRET 0000040
|
|
|
--#define OFILL 0000100
|
|
|
--#define OFDEL 0000200
|
|
|
--#define NLDLY 0000400
|
|
|
--#define NL0 0000000
|
|
|
--#define NL1 0000400
|
|
|
--#define CRDLY 0003000
|
|
|
--#define CR0 0000000
|
|
|
--#define CR1 0001000
|
|
|
--#define CR2 0002000
|
|
|
--#define CR3 0003000
|
|
|
--#define TABDLY 0014000
|
|
|
--#define TAB0 0000000
|
|
|
--#define TAB1 0004000
|
|
|
--#define TAB2 0010000
|
|
|
--#define TAB3 0014000
|
|
|
--#define BSDLY 0020000
|
|
|
--#define BS0 0000000
|
|
|
--#define BS1 0020000
|
|
|
--#define FFDLY 0100000
|
|
|
--#define FF0 0000000
|
|
|
--#define FF1 0100000
|
|
|
--
|
|
|
--#define VTDLY 0040000
|
|
|
--#define VT0 0000000
|
|
|
--#define VT1 0040000
|
|
|
--
|
|
|
--#define B0 0000000
|
|
|
--#define B50 0000001
|
|
|
--#define B75 0000002
|
|
|
--#define B110 0000003
|
|
|
--#define B134 0000004
|
|
|
--#define B150 0000005
|
|
|
--#define B200 0000006
|
|
|
--#define B300 0000007
|
|
|
--#define B600 0000010
|
|
|
--#define B1200 0000011
|
|
|
--#define B1800 0000012
|
|
|
--#define B2400 0000013
|
|
|
--#define B4800 0000014
|
|
|
--#define B9600 0000015
|
|
|
--#define B19200 0000016
|
|
|
--#define B38400 0000017
|
|
|
--
|
|
|
--#define B57600 0010001
|
|
|
--#define B115200 0010002
|
|
|
--#define B230400 0010003
|
|
|
--#define B460800 0010004
|
|
|
--#define B500000 0010005
|
|
|
--#define B576000 0010006
|
|
|
--#define B921600 0010007
|
|
|
--#define B1000000 0010010
|
|
|
--#define B1152000 0010011
|
|
|
--#define B1500000 0010012
|
|
|
--#define B2000000 0010013
|
|
|
--#define B2500000 0010014
|
|
|
--#define B3000000 0010015
|
|
|
--#define B3500000 0010016
|
|
|
--#define B4000000 0010017
|
|
|
--
|
|
|
--#define CBAUD 0010017
|
|
|
--
|
|
|
--#define CSIZE 0000060
|
|
|
--#define CS5 0000000
|
|
|
--#define CS6 0000020
|
|
|
--#define CS7 0000040
|
|
|
--#define CS8 0000060
|
|
|
--#define CSTOPB 0000100
|
|
|
--#define CREAD 0000200
|
|
|
--#define PARENB 0000400
|
|
|
--#define PARODD 0001000
|
|
|
--#define HUPCL 0002000
|
|
|
--#define CLOCAL 0004000
|
|
|
--
|
|
|
--#define ISIG 0000001
|
|
|
--#define ICANON 0000002
|
|
|
--#define ECHO 0000010
|
|
|
--#define ECHOE 0000020
|
|
|
--#define ECHOK 0000040
|
|
|
--#define ECHONL 0000100
|
|
|
--#define NOFLSH 0000200
|
|
|
--#define TOSTOP 0000400
|
|
|
--#define IEXTEN 0100000
|
|
|
--
|
|
|
--#define ECHOCTL 0001000
|
|
|
--#define ECHOPRT 0002000
|
|
|
--#define ECHOKE 0004000
|
|
|
--#define FLUSHO 0010000
|
|
|
--#define PENDIN 0040000
|
|
|
--
|
|
|
--#define TCOOFF 0
|
|
|
--#define TCOON 1
|
|
|
--#define TCIOFF 2
|
|
|
--#define TCION 3
|
|
|
--
|
|
|
--#define TCIFLUSH 0
|
|
|
--#define TCOFLUSH 1
|
|
|
--#define TCIOFLUSH 2
|
|
|
--
|
|
|
--#define TCSANOW 0
|
|
|
--#define TCSADRAIN 1
|
|
|
--#define TCSAFLUSH 2
|
|
|
--
|
|
|
--#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
--#define CBAUDEX 0010000
|
|
|
--#define CRTSCTS 020000000000
|
|
|
--#define EXTPROC 0200000
|
|
|
--#define XTABS 0014000
|
|
|
--#endif
|
|
|
---- a/arch/arm/pthread_arch.h
|
|
|
-+++ b/arch/arm/pthread_arch.h
|
|
|
-@@ -27,4 +27,4 @@ static inline pthread_t __pthread_self()
|
|
|
- #define TLS_ABOVE_TP
|
|
|
- #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 8)
|
|
|
-
|
|
|
--#define CANCEL_REG_IP 18
|
|
|
-+#define MC_PC arm_pc
|
|
|
---- a/arch/arm/reloc.h
|
|
|
-+++ b/arch/arm/reloc.h
|
|
|
-@@ -6,10 +6,10 @@
|
|
|
- #define ENDIAN_SUFFIX ""
|
|
|
- #endif
|
|
|
-
|
|
|
--#if __SOFTFP__
|
|
|
--#define FP_SUFFIX ""
|
|
|
--#else
|
|
|
-+#if __ARM_PCS_VFP
|
|
|
- #define FP_SUFFIX "hf"
|
|
|
-+#else
|
|
|
-+#define FP_SUFFIX ""
|
|
|
- #endif
|
|
|
-
|
|
|
- #define LDSO_ARCH "arm" ENDIAN_SUFFIX FP_SUFFIX
|
|
|
-@@ -28,10 +28,5 @@
|
|
|
- #define REL_TPOFF R_ARM_TLS_TPOFF32
|
|
|
- //#define REL_TLSDESC R_ARM_TLS_DESC
|
|
|
-
|
|
|
--#ifdef __thumb__
|
|
|
- #define CRTJMP(pc,sp) __asm__ __volatile__( \
|
|
|
- "mov sp,%1 ; bx %0" : : "r"(pc), "r"(sp) : "memory" )
|
|
|
--#else
|
|
|
--#define CRTJMP(pc,sp) __asm__ __volatile__( \
|
|
|
-- "mov sp,%1 ; tst %0,#1 ; moveq pc,%0 ; bx %0" : : "r"(pc), "r"(sp) : "memory" )
|
|
|
--#endif
|
|
|
---- a/arch/arm/src/__aeabi_atexit.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,6 +0,0 @@
|
|
|
--int __cxa_atexit(void (*func)(void *), void *arg, void *dso);
|
|
|
--
|
|
|
--int __aeabi_atexit (void *obj, void (*func) (void *), void *d)
|
|
|
--{
|
|
|
-- return __cxa_atexit (func, obj, d);
|
|
|
--}
|
|
|
---- a/arch/arm/src/__aeabi_memclr.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,9 +0,0 @@
|
|
|
--#include <string.h>
|
|
|
--#include "libc.h"
|
|
|
--
|
|
|
--void __aeabi_memclr(void *dest, size_t n)
|
|
|
--{
|
|
|
-- memset(dest, 0, n);
|
|
|
--}
|
|
|
--weak_alias(__aeabi_memclr, __aeabi_memclr4);
|
|
|
--weak_alias(__aeabi_memclr, __aeabi_memclr8);
|
|
|
---- a/arch/arm/src/__aeabi_memcpy.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,9 +0,0 @@
|
|
|
--#include <string.h>
|
|
|
--#include "libc.h"
|
|
|
--
|
|
|
--void __aeabi_memcpy(void *restrict dest, const void *restrict src, size_t n)
|
|
|
--{
|
|
|
-- memcpy(dest, src, n);
|
|
|
--}
|
|
|
--weak_alias(__aeabi_memcpy, __aeabi_memcpy4);
|
|
|
--weak_alias(__aeabi_memcpy, __aeabi_memcpy8);
|
|
|
---- a/arch/arm/src/__aeabi_memmove.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,9 +0,0 @@
|
|
|
--#include <string.h>
|
|
|
--#include "libc.h"
|
|
|
--
|
|
|
--void __aeabi_memmove(void *dest, const void *src, size_t n)
|
|
|
--{
|
|
|
-- memmove(dest, src, n);
|
|
|
--}
|
|
|
--weak_alias(__aeabi_memmove, __aeabi_memmove4);
|
|
|
--weak_alias(__aeabi_memmove, __aeabi_memmove8);
|
|
|
---- a/arch/arm/src/__aeabi_memset.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,9 +0,0 @@
|
|
|
--#include <string.h>
|
|
|
--#include "libc.h"
|
|
|
--
|
|
|
--void __aeabi_memset(void *dest, size_t n, int c)
|
|
|
--{
|
|
|
-- memset(dest, c, n);
|
|
|
--}
|
|
|
--weak_alias(__aeabi_memset, __aeabi_memset4);
|
|
|
--weak_alias(__aeabi_memset, __aeabi_memset8);
|
|
|
---- a/arch/arm/src/__set_thread_area.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,49 +0,0 @@
|
|
|
--#include <stdint.h>
|
|
|
--#include <elf.h>
|
|
|
--#include "pthread_impl.h"
|
|
|
--#include "libc.h"
|
|
|
--
|
|
|
--#define HWCAP_TLS (1 << 15)
|
|
|
--
|
|
|
--extern const unsigned char __attribute__((__visibility__("hidden")))
|
|
|
-- __a_barrier_dummy[], __a_barrier_oldkuser[],
|
|
|
-- __a_barrier_v6[], __a_barrier_v7[],
|
|
|
-- __a_cas_dummy[], __a_cas_v6[], __a_cas_v7[],
|
|
|
-- __a_gettp_dummy[];
|
|
|
--
|
|
|
--#define __a_barrier_kuser 0xffff0fa0
|
|
|
--#define __a_cas_kuser 0xffff0fc0
|
|
|
--#define __a_gettp_kuser 0xffff0fe0
|
|
|
--
|
|
|
--extern uintptr_t __attribute__((__visibility__("hidden")))
|
|
|
-- __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr;
|
|
|
--
|
|
|
--#define SET(op,ver) (__a_##op##_ptr = \
|
|
|
-- (uintptr_t)__a_##op##_##ver - (uintptr_t)__a_##op##_dummy)
|
|
|
--
|
|
|
--int __set_thread_area(void *p)
|
|
|
--{
|
|
|
--#if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7
|
|
|
-- if (__hwcap & HWCAP_TLS) {
|
|
|
-- size_t *aux;
|
|
|
-- SET(cas, v7);
|
|
|
-- SET(barrier, v7);
|
|
|
-- for (aux=libc.auxv; *aux; aux+=2) {
|
|
|
-- if (*aux != AT_PLATFORM) continue;
|
|
|
-- const char *s = (void *)aux[1];
|
|
|
-- if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break;
|
|
|
-- SET(cas, v6);
|
|
|
-- SET(barrier, v6);
|
|
|
-- break;
|
|
|
-- }
|
|
|
-- } else {
|
|
|
-- int ver = *(int *)0xffff0ffc;
|
|
|
-- SET(gettp, kuser);
|
|
|
-- SET(cas, kuser);
|
|
|
-- SET(barrier, kuser);
|
|
|
-- if (ver < 2) a_crash();
|
|
|
-- if (ver < 3) SET(barrier, oldkuser);
|
|
|
-- }
|
|
|
--#endif
|
|
|
-- return __syscall(0xf0005, p);
|
|
|
--}
|
|
|
---- a/arch/arm/src/arm/atomics.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,116 +0,0 @@
|
|
|
--.text
|
|
|
--
|
|
|
--.global __a_barrier
|
|
|
--.hidden __a_barrier
|
|
|
--.type __a_barrier,%function
|
|
|
--__a_barrier:
|
|
|
-- ldr ip,1f
|
|
|
-- ldr ip,[pc,ip]
|
|
|
-- add pc,pc,ip
|
|
|
--1: .word __a_barrier_ptr-1b
|
|
|
--.global __a_barrier_dummy
|
|
|
--.hidden __a_barrier_dummy
|
|
|
--__a_barrier_dummy:
|
|
|
-- tst lr,#1
|
|
|
-- moveq pc,lr
|
|
|
-- bx lr
|
|
|
--.global __a_barrier_oldkuser
|
|
|
--.hidden __a_barrier_oldkuser
|
|
|
--__a_barrier_oldkuser:
|
|
|
-- push {r0,r1,r2,r3,ip,lr}
|
|
|
-- mov r1,r0
|
|
|
-- mov r2,sp
|
|
|
-- ldr ip,=0xffff0fc0
|
|
|
-- mov lr,pc
|
|
|
-- mov pc,ip
|
|
|
-- pop {r0,r1,r2,r3,ip,lr}
|
|
|
-- tst lr,#1
|
|
|
-- moveq pc,lr
|
|
|
-- bx lr
|
|
|
--.global __a_barrier_v6
|
|
|
--.hidden __a_barrier_v6
|
|
|
--__a_barrier_v6:
|
|
|
-- mcr p15,0,r0,c7,c10,5
|
|
|
-- bx lr
|
|
|
--.global __a_barrier_v7
|
|
|
--.hidden __a_barrier_v7
|
|
|
--__a_barrier_v7:
|
|
|
-- .word 0xf57ff05b /* dmb ish */
|
|
|
-- bx lr
|
|
|
--
|
|
|
--.global __a_cas
|
|
|
--.hidden __a_cas
|
|
|
--.type __a_cas,%function
|
|
|
--__a_cas:
|
|
|
-- ldr ip,1f
|
|
|
-- ldr ip,[pc,ip]
|
|
|
-- add pc,pc,ip
|
|
|
--1: .word __a_cas_ptr-1b
|
|
|
--.global __a_cas_dummy
|
|
|
--.hidden __a_cas_dummy
|
|
|
--__a_cas_dummy:
|
|
|
-- mov r3,r0
|
|
|
-- ldr r0,[r2]
|
|
|
-- subs r0,r3,r0
|
|
|
-- streq r1,[r2]
|
|
|
-- tst lr,#1
|
|
|
-- moveq pc,lr
|
|
|
-- bx lr
|
|
|
--.global __a_cas_v6
|
|
|
--.hidden __a_cas_v6
|
|
|
--__a_cas_v6:
|
|
|
-- mov r3,r0
|
|
|
-- mcr p15,0,r0,c7,c10,5
|
|
|
--1: .word 0xe1920f9f /* ldrex r0,[r2] */
|
|
|
-- subs r0,r3,r0
|
|
|
-- .word 0x01820f91 /* strexeq r0,r1,[r2] */
|
|
|
-- teqeq r0,#1
|
|
|
-- beq 1b
|
|
|
-- mcr p15,0,r0,c7,c10,5
|
|
|
-- bx lr
|
|
|
--.global __a_cas_v7
|
|
|
--.hidden __a_cas_v7
|
|
|
--__a_cas_v7:
|
|
|
-- mov r3,r0
|
|
|
-- .word 0xf57ff05b /* dmb ish */
|
|
|
--1: .word 0xe1920f9f /* ldrex r0,[r2] */
|
|
|
-- subs r0,r3,r0
|
|
|
-- .word 0x01820f91 /* strexeq r0,r1,[r2] */
|
|
|
-- teqeq r0,#1
|
|
|
-- beq 1b
|
|
|
-- .word 0xf57ff05b /* dmb ish */
|
|
|
-- bx lr
|
|
|
--
|
|
|
--.global __aeabi_read_tp
|
|
|
--.type __aeabi_read_tp,%function
|
|
|
--__aeabi_read_tp:
|
|
|
--
|
|
|
--.global __a_gettp
|
|
|
--.hidden __a_gettp
|
|
|
--.type __a_gettp,%function
|
|
|
--__a_gettp:
|
|
|
-- ldr r0,1f
|
|
|
-- ldr r0,[pc,r0]
|
|
|
-- add pc,pc,r0
|
|
|
--1: .word __a_gettp_ptr-1b
|
|
|
--.global __a_gettp_dummy
|
|
|
--.hidden __a_gettp_dummy
|
|
|
--__a_gettp_dummy:
|
|
|
-- mrc p15,0,r0,c13,c0,3
|
|
|
-- bx lr
|
|
|
--
|
|
|
--.data
|
|
|
--.global __a_barrier_ptr
|
|
|
--.hidden __a_barrier_ptr
|
|
|
--__a_barrier_ptr:
|
|
|
-- .word 0
|
|
|
--
|
|
|
--.global __a_cas_ptr
|
|
|
--.hidden __a_cas_ptr
|
|
|
--__a_cas_ptr:
|
|
|
-- .word 0
|
|
|
--
|
|
|
--.global __a_gettp_ptr
|
|
|
--.hidden __a_gettp_ptr
|
|
|
--__a_gettp_ptr:
|
|
|
-- .word 0
|
|
|
---- a/arch/arm/src/find_exidx.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,42 +0,0 @@
|
|
|
--#define _GNU_SOURCE
|
|
|
--#include <link.h>
|
|
|
--#include <stdint.h>
|
|
|
--
|
|
|
--struct find_exidx_data {
|
|
|
-- uintptr_t pc, exidx_start;
|
|
|
-- int exidx_len;
|
|
|
--};
|
|
|
--
|
|
|
--static int find_exidx(struct dl_phdr_info *info, size_t size, void *ptr)
|
|
|
--{
|
|
|
-- struct find_exidx_data *data = ptr;
|
|
|
-- const ElfW(Phdr) *phdr = info->dlpi_phdr;
|
|
|
-- uintptr_t addr, exidx_start = 0;
|
|
|
-- int i, match = 0, exidx_len = 0;
|
|
|
--
|
|
|
-- for (i = info->dlpi_phnum; i > 0; i--, phdr++) {
|
|
|
-- addr = info->dlpi_addr + phdr->p_vaddr;
|
|
|
-- switch (phdr->p_type) {
|
|
|
-- case PT_LOAD:
|
|
|
-- match |= data->pc >= addr && data->pc < addr + phdr->p_memsz;
|
|
|
-- break;
|
|
|
-- case PT_ARM_EXIDX:
|
|
|
-- exidx_start = addr;
|
|
|
-- exidx_len = phdr->p_memsz;
|
|
|
-- break;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- data->exidx_start = exidx_start;
|
|
|
-- data->exidx_len = exidx_len;
|
|
|
-- return match;
|
|
|
--}
|
|
|
--
|
|
|
--uintptr_t __gnu_Unwind_Find_exidx(uintptr_t pc, int *pcount)
|
|
|
--{
|
|
|
-- struct find_exidx_data data;
|
|
|
-- data.pc = pc;
|
|
|
-- if (dl_iterate_phdr(find_exidx, &data) <= 0)
|
|
|
-- return 0;
|
|
|
-- *pcount = data.exidx_len / 8;
|
|
|
-- return data.exidx_start;
|
|
|
--}
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/generic/bits/errno.h
|
|
|
-@@ -0,0 +1,134 @@
|
|
|
-+#define EPERM 1
|
|
|
-+#define ENOENT 2
|
|
|
-+#define ESRCH 3
|
|
|
-+#define EINTR 4
|
|
|
-+#define EIO 5
|
|
|
-+#define ENXIO 6
|
|
|
-+#define E2BIG 7
|
|
|
-+#define ENOEXEC 8
|
|
|
-+#define EBADF 9
|
|
|
-+#define ECHILD 10
|
|
|
-+#define EAGAIN 11
|
|
|
-+#define ENOMEM 12
|
|
|
-+#define EACCES 13
|
|
|
-+#define EFAULT 14
|
|
|
-+#define ENOTBLK 15
|
|
|
-+#define EBUSY 16
|
|
|
-+#define EEXIST 17
|
|
|
-+#define EXDEV 18
|
|
|
-+#define ENODEV 19
|
|
|
-+#define ENOTDIR 20
|
|
|
-+#define EISDIR 21
|
|
|
-+#define EINVAL 22
|
|
|
-+#define ENFILE 23
|
|
|
-+#define EMFILE 24
|
|
|
-+#define ENOTTY 25
|
|
|
-+#define ETXTBSY 26
|
|
|
-+#define EFBIG 27
|
|
|
-+#define ENOSPC 28
|
|
|
-+#define ESPIPE 29
|
|
|
-+#define EROFS 30
|
|
|
-+#define EMLINK 31
|
|
|
-+#define EPIPE 32
|
|
|
-+#define EDOM 33
|
|
|
-+#define ERANGE 34
|
|
|
-+#define EDEADLK 35
|
|
|
-+#define ENAMETOOLONG 36
|
|
|
-+#define ENOLCK 37
|
|
|
-+#define ENOSYS 38
|
|
|
-+#define ENOTEMPTY 39
|
|
|
-+#define ELOOP 40
|
|
|
-+#define EWOULDBLOCK EAGAIN
|
|
|
-+#define ENOMSG 42
|
|
|
-+#define EIDRM 43
|
|
|
-+#define ECHRNG 44
|
|
|
-+#define EL2NSYNC 45
|
|
|
-+#define EL3HLT 46
|
|
|
-+#define EL3RST 47
|
|
|
-+#define ELNRNG 48
|
|
|
-+#define EUNATCH 49
|
|
|
-+#define ENOCSI 50
|
|
|
-+#define EL2HLT 51
|
|
|
-+#define EBADE 52
|
|
|
-+#define EBADR 53
|
|
|
-+#define EXFULL 54
|
|
|
-+#define ENOANO 55
|
|
|
-+#define EBADRQC 56
|
|
|
-+#define EBADSLT 57
|
|
|
-+#define EDEADLOCK EDEADLK
|
|
|
-+#define EBFONT 59
|
|
|
-+#define ENOSTR 60
|
|
|
-+#define ENODATA 61
|
|
|
-+#define ETIME 62
|
|
|
-+#define ENOSR 63
|
|
|
-+#define ENONET 64
|
|
|
-+#define ENOPKG 65
|
|
|
-+#define EREMOTE 66
|
|
|
-+#define ENOLINK 67
|
|
|
-+#define EADV 68
|
|
|
-+#define ESRMNT 69
|
|
|
-+#define ECOMM 70
|
|
|
-+#define EPROTO 71
|
|
|
-+#define EMULTIHOP 72
|
|
|
-+#define EDOTDOT 73
|
|
|
-+#define EBADMSG 74
|
|
|
-+#define EOVERFLOW 75
|
|
|
-+#define ENOTUNIQ 76
|
|
|
-+#define EBADFD 77
|
|
|
-+#define EREMCHG 78
|
|
|
-+#define ELIBACC 79
|
|
|
-+#define ELIBBAD 80
|
|
|
-+#define ELIBSCN 81
|
|
|
-+#define ELIBMAX 82
|
|
|
-+#define ELIBEXEC 83
|
|
|
-+#define EILSEQ 84
|
|
|
-+#define ERESTART 85
|
|
|
-+#define ESTRPIPE 86
|
|
|
-+#define EUSERS 87
|
|
|
-+#define ENOTSOCK 88
|
|
|
-+#define EDESTADDRREQ 89
|
|
|
-+#define EMSGSIZE 90
|
|
|
-+#define EPROTOTYPE 91
|
|
|
-+#define ENOPROTOOPT 92
|
|
|
-+#define EPROTONOSUPPORT 93
|
|
|
-+#define ESOCKTNOSUPPORT 94
|
|
|
-+#define EOPNOTSUPP 95
|
|
|
-+#define ENOTSUP EOPNOTSUPP
|
|
|
-+#define EPFNOSUPPORT 96
|
|
|
-+#define EAFNOSUPPORT 97
|
|
|
-+#define EADDRINUSE 98
|
|
|
-+#define EADDRNOTAVAIL 99
|
|
|
-+#define ENETDOWN 100
|
|
|
-+#define ENETUNREACH 101
|
|
|
-+#define ENETRESET 102
|
|
|
-+#define ECONNABORTED 103
|
|
|
-+#define ECONNRESET 104
|
|
|
-+#define ENOBUFS 105
|
|
|
-+#define EISCONN 106
|
|
|
-+#define ENOTCONN 107
|
|
|
-+#define ESHUTDOWN 108
|
|
|
-+#define ETOOMANYREFS 109
|
|
|
-+#define ETIMEDOUT 110
|
|
|
-+#define ECONNREFUSED 111
|
|
|
-+#define EHOSTDOWN 112
|
|
|
-+#define EHOSTUNREACH 113
|
|
|
-+#define EALREADY 114
|
|
|
-+#define EINPROGRESS 115
|
|
|
-+#define ESTALE 116
|
|
|
-+#define EUCLEAN 117
|
|
|
-+#define ENOTNAM 118
|
|
|
-+#define ENAVAIL 119
|
|
|
-+#define EISNAM 120
|
|
|
-+#define EREMOTEIO 121
|
|
|
-+#define EDQUOT 122
|
|
|
-+#define ENOMEDIUM 123
|
|
|
-+#define EMEDIUMTYPE 124
|
|
|
-+#define ECANCELED 125
|
|
|
-+#define ENOKEY 126
|
|
|
-+#define EKEYEXPIRED 127
|
|
|
-+#define EKEYREVOKED 128
|
|
|
-+#define EKEYREJECTED 129
|
|
|
-+#define EOWNERDEAD 130
|
|
|
-+#define ENOTRECOVERABLE 131
|
|
|
-+#define ERFKILL 132
|
|
|
-+#define EHWPOISON 133
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/generic/bits/fcntl.h
|
|
|
-@@ -0,0 +1,40 @@
|
|
|
-+#define O_CREAT 0100
|
|
|
-+#define O_EXCL 0200
|
|
|
-+#define O_NOCTTY 0400
|
|
|
-+#define O_TRUNC 01000
|
|
|
-+#define O_APPEND 02000
|
|
|
-+#define O_NONBLOCK 04000
|
|
|
-+#define O_DSYNC 010000
|
|
|
-+#define O_SYNC 04010000
|
|
|
-+#define O_RSYNC 04010000
|
|
|
-+#define O_DIRECTORY 0200000
|
|
|
-+#define O_NOFOLLOW 0400000
|
|
|
-+#define O_CLOEXEC 02000000
|
|
|
-+
|
|
|
-+#define O_ASYNC 020000
|
|
|
-+#define O_DIRECT 040000
|
|
|
-+#define O_LARGEFILE 0100000
|
|
|
-+#define O_NOATIME 01000000
|
|
|
-+#define O_PATH 010000000
|
|
|
-+#define O_TMPFILE 020200000
|
|
|
-+#define O_NDELAY O_NONBLOCK
|
|
|
-+
|
|
|
-+#define F_DUPFD 0
|
|
|
-+#define F_GETFD 1
|
|
|
-+#define F_SETFD 2
|
|
|
-+#define F_GETFL 3
|
|
|
-+#define F_SETFL 4
|
|
|
-+
|
|
|
-+#define F_SETOWN 8
|
|
|
-+#define F_GETOWN 9
|
|
|
-+#define F_SETSIG 10
|
|
|
-+#define F_GETSIG 11
|
|
|
-+
|
|
|
-+#define F_GETLK 12
|
|
|
-+#define F_SETLK 13
|
|
|
-+#define F_SETLKW 14
|
|
|
-+
|
|
|
-+#define F_SETOWN_EX 15
|
|
|
-+#define F_GETOWN_EX 16
|
|
|
-+
|
|
|
-+#define F_GETOWNER_UIDS 17
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/generic/bits/fenv.h
|
|
|
-@@ -0,0 +1,10 @@
|
|
|
-+#define FE_ALL_EXCEPT 0
|
|
|
-+#define FE_TONEAREST 0
|
|
|
-+
|
|
|
-+typedef unsigned long fexcept_t;
|
|
|
-+
|
|
|
-+typedef struct {
|
|
|
-+ unsigned long __cw;
|
|
|
-+} fenv_t;
|
|
|
-+
|
|
|
-+#define FE_DFL_ENV ((const fenv_t *) -1)
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/generic/bits/ioctl.h
|
|
|
-@@ -0,0 +1,197 @@
|
|
|
-+#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
|
|
|
-+#define _IOC_NONE 0U
|
|
|
-+#define _IOC_WRITE 1U
|
|
|
-+#define _IOC_READ 2U
|
|
|
-+
|
|
|
-+#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
|
|
|
-+#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
|
|
|
-+#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
|
|
|
-+#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
|
|
|
-+
|
|
|
-+#define TCGETS 0x5401
|
|
|
-+#define TCSETS 0x5402
|
|
|
-+#define TCSETSW 0x5403
|
|
|
-+#define TCSETSF 0x5404
|
|
|
-+#define TCGETA 0x5405
|
|
|
-+#define TCSETA 0x5406
|
|
|
-+#define TCSETAW 0x5407
|
|
|
-+#define TCSETAF 0x5408
|
|
|
-+#define TCSBRK 0x5409
|
|
|
-+#define TCXONC 0x540A
|
|
|
-+#define TCFLSH 0x540B
|
|
|
-+#define TIOCEXCL 0x540C
|
|
|
-+#define TIOCNXCL 0x540D
|
|
|
-+#define TIOCSCTTY 0x540E
|
|
|
-+#define TIOCGPGRP 0x540F
|
|
|
-+#define TIOCSPGRP 0x5410
|
|
|
-+#define TIOCOUTQ 0x5411
|
|
|
-+#define TIOCSTI 0x5412
|
|
|
-+#define TIOCGWINSZ 0x5413
|
|
|
-+#define TIOCSWINSZ 0x5414
|
|
|
-+#define TIOCMGET 0x5415
|
|
|
-+#define TIOCMBIS 0x5416
|
|
|
-+#define TIOCMBIC 0x5417
|
|
|
-+#define TIOCMSET 0x5418
|
|
|
-+#define TIOCGSOFTCAR 0x5419
|
|
|
-+#define TIOCSSOFTCAR 0x541A
|
|
|
-+#define FIONREAD 0x541B
|
|
|
-+#define TIOCINQ FIONREAD
|
|
|
-+#define TIOCLINUX 0x541C
|
|
|
-+#define TIOCCONS 0x541D
|
|
|
-+#define TIOCGSERIAL 0x541E
|
|
|
-+#define TIOCSSERIAL 0x541F
|
|
|
-+#define TIOCPKT 0x5420
|
|
|
-+#define FIONBIO 0x5421
|
|
|
-+#define TIOCNOTTY 0x5422
|
|
|
-+#define TIOCSETD 0x5423
|
|
|
-+#define TIOCGETD 0x5424
|
|
|
-+#define TCSBRKP 0x5425
|
|
|
-+#define TIOCTTYGSTRUCT 0x5426
|
|
|
-+#define TIOCSBRK 0x5427
|
|
|
-+#define TIOCCBRK 0x5428
|
|
|
-+#define TIOCGSID 0x5429
|
|
|
-+#define TIOCGPTN 0x80045430
|
|
|
-+#define TIOCSPTLCK 0x40045431
|
|
|
-+#define TCGETX 0x5432
|
|
|
-+#define TCSETX 0x5433
|
|
|
-+#define TCSETXF 0x5434
|
|
|
-+#define TCSETXW 0x5435
|
|
|
-+
|
|
|
-+#define FIONCLEX 0x5450
|
|
|
-+#define FIOCLEX 0x5451
|
|
|
-+#define FIOASYNC 0x5452
|
|
|
-+#define TIOCSERCONFIG 0x5453
|
|
|
-+#define TIOCSERGWILD 0x5454
|
|
|
-+#define TIOCSERSWILD 0x5455
|
|
|
-+#define TIOCGLCKTRMIOS 0x5456
|
|
|
-+#define TIOCSLCKTRMIOS 0x5457
|
|
|
-+#define TIOCSERGSTRUCT 0x5458
|
|
|
-+#define TIOCSERGETLSR 0x5459
|
|
|
-+#define TIOCSERGETMULTI 0x545A
|
|
|
-+#define TIOCSERSETMULTI 0x545B
|
|
|
-+
|
|
|
-+#define TIOCMIWAIT 0x545C
|
|
|
-+#define TIOCGICOUNT 0x545D
|
|
|
-+#define TIOCGHAYESESP 0x545E
|
|
|
-+#define TIOCSHAYESESP 0x545F
|
|
|
-+#define FIOQSIZE 0x5460
|
|
|
-+
|
|
|
-+#define TIOCPKT_DATA 0
|
|
|
-+#define TIOCPKT_FLUSHREAD 1
|
|
|
-+#define TIOCPKT_FLUSHWRITE 2
|
|
|
-+#define TIOCPKT_STOP 4
|
|
|
-+#define TIOCPKT_START 8
|
|
|
-+#define TIOCPKT_NOSTOP 16
|
|
|
-+#define TIOCPKT_DOSTOP 32
|
|
|
-+#define TIOCPKT_IOCTL 64
|
|
|
-+
|
|
|
-+#define TIOCSER_TEMT 0x01
|
|
|
-+
|
|
|
-+struct winsize {
|
|
|
-+ unsigned short ws_row;
|
|
|
-+ unsigned short ws_col;
|
|
|
-+ unsigned short ws_xpixel;
|
|
|
-+ unsigned short ws_ypixel;
|
|
|
-+};
|
|
|
-+
|
|
|
-+#define TIOCM_LE 0x001
|
|
|
-+#define TIOCM_DTR 0x002
|
|
|
-+#define TIOCM_RTS 0x004
|
|
|
-+#define TIOCM_ST 0x008
|
|
|
-+#define TIOCM_SR 0x010
|
|
|
-+#define TIOCM_CTS 0x020
|
|
|
-+#define TIOCM_CAR 0x040
|
|
|
-+#define TIOCM_RNG 0x080
|
|
|
-+#define TIOCM_DSR 0x100
|
|
|
-+#define TIOCM_CD TIOCM_CAR
|
|
|
-+#define TIOCM_RI TIOCM_RNG
|
|
|
-+#define TIOCM_OUT1 0x2000
|
|
|
-+#define TIOCM_OUT2 0x4000
|
|
|
-+#define TIOCM_LOOP 0x8000
|
|
|
-+#define TIOCM_MODEM_BITS TIOCM_OUT2
|
|
|
-+
|
|
|
-+#define N_TTY 0
|
|
|
-+#define N_SLIP 1
|
|
|
-+#define N_MOUSE 2
|
|
|
-+#define N_PPP 3
|
|
|
-+#define N_STRIP 4
|
|
|
-+#define N_AX25 5
|
|
|
-+#define N_X25 6
|
|
|
-+#define N_6PACK 7
|
|
|
-+#define N_MASC 8
|
|
|
-+#define N_R3964 9
|
|
|
-+#define N_PROFIBUS_FDL 10
|
|
|
-+#define N_IRDA 11
|
|
|
-+#define N_SMSBLOCK 12
|
|
|
-+#define N_HDLC 13
|
|
|
-+#define N_SYNC_PPP 14
|
|
|
-+#define N_HCI 15
|
|
|
-+
|
|
|
-+#define FIOSETOWN 0x8901
|
|
|
-+#define SIOCSPGRP 0x8902
|
|
|
-+#define FIOGETOWN 0x8903
|
|
|
-+#define SIOCGPGRP 0x8904
|
|
|
-+#define SIOCATMARK 0x8905
|
|
|
-+#define SIOCGSTAMP 0x8906
|
|
|
-+
|
|
|
-+#define SIOCADDRT 0x890B
|
|
|
-+#define SIOCDELRT 0x890C
|
|
|
-+#define SIOCRTMSG 0x890D
|
|
|
-+
|
|
|
-+#define SIOCGIFNAME 0x8910
|
|
|
-+#define SIOCSIFLINK 0x8911
|
|
|
-+#define SIOCGIFCONF 0x8912
|
|
|
-+#define SIOCGIFFLAGS 0x8913
|
|
|
-+#define SIOCSIFFLAGS 0x8914
|
|
|
-+#define SIOCGIFADDR 0x8915
|
|
|
-+#define SIOCSIFADDR 0x8916
|
|
|
-+#define SIOCGIFDSTADDR 0x8917
|
|
|
-+#define SIOCSIFDSTADDR 0x8918
|
|
|
-+#define SIOCGIFBRDADDR 0x8919
|
|
|
-+#define SIOCSIFBRDADDR 0x891a
|
|
|
-+#define SIOCGIFNETMASK 0x891b
|
|
|
-+#define SIOCSIFNETMASK 0x891c
|
|
|
-+#define SIOCGIFMETRIC 0x891d
|
|
|
-+#define SIOCSIFMETRIC 0x891e
|
|
|
-+#define SIOCGIFMEM 0x891f
|
|
|
-+#define SIOCSIFMEM 0x8920
|
|
|
-+#define SIOCGIFMTU 0x8921
|
|
|
-+#define SIOCSIFMTU 0x8922
|
|
|
-+#define SIOCSIFHWADDR 0x8924
|
|
|
-+#define SIOCGIFENCAP 0x8925
|
|
|
-+#define SIOCSIFENCAP 0x8926
|
|
|
-+#define SIOCGIFHWADDR 0x8927
|
|
|
-+#define SIOCGIFSLAVE 0x8929
|
|
|
-+#define SIOCSIFSLAVE 0x8930
|
|
|
-+#define SIOCADDMULTI 0x8931
|
|
|
-+#define SIOCDELMULTI 0x8932
|
|
|
-+#define SIOCGIFINDEX 0x8933
|
|
|
-+#define SIOGIFINDEX SIOCGIFINDEX
|
|
|
-+#define SIOCSIFPFLAGS 0x8934
|
|
|
-+#define SIOCGIFPFLAGS 0x8935
|
|
|
-+#define SIOCDIFADDR 0x8936
|
|
|
-+#define SIOCSIFHWBROADCAST 0x8937
|
|
|
-+#define SIOCGIFCOUNT 0x8938
|
|
|
-+
|
|
|
-+#define SIOCGIFBR 0x8940
|
|
|
-+#define SIOCSIFBR 0x8941
|
|
|
-+
|
|
|
-+#define SIOCGIFTXQLEN 0x8942
|
|
|
-+#define SIOCSIFTXQLEN 0x8943
|
|
|
-+
|
|
|
-+#define SIOCDARP 0x8953
|
|
|
-+#define SIOCGARP 0x8954
|
|
|
-+#define SIOCSARP 0x8955
|
|
|
-+
|
|
|
-+#define SIOCDRARP 0x8960
|
|
|
-+#define SIOCGRARP 0x8961
|
|
|
-+#define SIOCSRARP 0x8962
|
|
|
-+
|
|
|
-+#define SIOCGIFMAP 0x8970
|
|
|
-+#define SIOCSIFMAP 0x8971
|
|
|
-+
|
|
|
-+#define SIOCADDDLCI 0x8980
|
|
|
-+#define SIOCDELDLCI 0x8981
|
|
|
-+
|
|
|
-+#define SIOCDEVPRIVATE 0x89F0
|
|
|
-+#define SIOCPROTOPRIVATE 0x89E0
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/generic/bits/ipc.h
|
|
|
-@@ -0,0 +1,14 @@
|
|
|
-+struct ipc_perm
|
|
|
-+{
|
|
|
-+ key_t __ipc_perm_key;
|
|
|
-+ uid_t uid;
|
|
|
-+ gid_t gid;
|
|
|
-+ uid_t cuid;
|
|
|
-+ gid_t cgid;
|
|
|
-+ mode_t mode;
|
|
|
-+ int __ipc_perm_seq;
|
|
|
-+ long __pad1;
|
|
|
-+ long __pad2;
|
|
|
-+};
|
|
|
-+
|
|
|
-+#define IPC_64 0x100
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/generic/bits/msg.h
|
|
|
-@@ -0,0 +1,16 @@
|
|
|
-+struct msqid_ds
|
|
|
-+{
|
|
|
-+ struct ipc_perm msg_perm;
|
|
|
-+ time_t msg_stime;
|
|
|
-+ int __unused1;
|
|
|
-+ time_t msg_rtime;
|
|
|
-+ int __unused2;
|
|
|
-+ time_t msg_ctime;
|
|
|
-+ int __unused3;
|
|
|
-+ unsigned long msg_cbytes;
|
|
|
-+ msgqnum_t msg_qnum;
|
|
|
-+ msglen_t msg_qbytes;
|
|
|
-+ pid_t msg_lspid;
|
|
|
-+ pid_t msg_lrpid;
|
|
|
-+ unsigned long __unused[2];
|
|
|
-+};
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/generic/bits/sem.h
|
|
|
-@@ -0,0 +1,16 @@
|
|
|
-+struct semid_ds {
|
|
|
-+ struct ipc_perm sem_perm;
|
|
|
-+ time_t sem_otime;
|
|
|
-+ time_t __unused1;
|
|
|
-+ time_t sem_ctime;
|
|
|
-+ time_t __unused2;
|
|
|
-+#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
-+ unsigned short sem_nsems;
|
|
|
-+ char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
-+#else
|
|
|
-+ char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
-+ unsigned short sem_nsems;
|
|
|
-+#endif
|
|
|
-+ time_t __unused3;
|
|
|
-+ time_t __unused4;
|
|
|
-+};
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/generic/bits/shm.h
|
|
|
-@@ -0,0 +1,29 @@
|
|
|
-+#define SHMLBA 4096
|
|
|
-+
|
|
|
-+struct shmid_ds
|
|
|
-+{
|
|
|
-+ struct ipc_perm shm_perm;
|
|
|
-+ size_t shm_segsz;
|
|
|
-+ time_t shm_atime;
|
|
|
-+ int __unused1;
|
|
|
-+ time_t shm_dtime;
|
|
|
-+ int __unused2;
|
|
|
-+ time_t shm_ctime;
|
|
|
-+ int __unused3;
|
|
|
-+ pid_t shm_cpid;
|
|
|
-+ pid_t shm_lpid;
|
|
|
-+ unsigned long shm_nattch;
|
|
|
-+ unsigned long __pad1;
|
|
|
-+ unsigned long __pad2;
|
|
|
-+};
|
|
|
-+
|
|
|
-+struct shminfo {
|
|
|
-+ unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
|
|
|
-+};
|
|
|
-+
|
|
|
-+struct shm_info {
|
|
|
-+ int __used_ids;
|
|
|
-+ unsigned long shm_tot, shm_rss, shm_swp;
|
|
|
-+ unsigned long __swap_attempts, __swap_successes;
|
|
|
-+};
|
|
|
-+
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/generic/bits/socket.h
|
|
|
-@@ -0,0 +1,17 @@
|
|
|
-+struct msghdr
|
|
|
-+{
|
|
|
-+ void *msg_name;
|
|
|
-+ socklen_t msg_namelen;
|
|
|
-+ struct iovec *msg_iov;
|
|
|
-+ int msg_iovlen;
|
|
|
-+ void *msg_control;
|
|
|
-+ socklen_t msg_controllen;
|
|
|
-+ int msg_flags;
|
|
|
-+};
|
|
|
-+
|
|
|
-+struct cmsghdr
|
|
|
-+{
|
|
|
-+ socklen_t cmsg_len;
|
|
|
-+ int cmsg_level;
|
|
|
-+ int cmsg_type;
|
|
|
-+};
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/generic/bits/statfs.h
|
|
|
-@@ -0,0 +1,7 @@
|
|
|
-+struct statfs {
|
|
|
-+ unsigned long f_type, f_bsize;
|
|
|
-+ fsblkcnt_t f_blocks, f_bfree, f_bavail;
|
|
|
-+ fsfilcnt_t f_files, f_ffree;
|
|
|
-+ fsid_t f_fsid;
|
|
|
-+ unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
|
|
|
-+};
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/generic/bits/stdarg.h
|
|
|
-@@ -0,0 +1,4 @@
|
|
|
-+#define va_start(v,l) __builtin_va_start(v,l)
|
|
|
-+#define va_end(v) __builtin_va_end(v)
|
|
|
-+#define va_arg(v,l) __builtin_va_arg(v,l)
|
|
|
-+#define va_copy(d,s) __builtin_va_copy(d,s)
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/generic/bits/termios.h
|
|
|
-@@ -0,0 +1,160 @@
|
|
|
-+struct termios
|
|
|
-+{
|
|
|
-+ tcflag_t c_iflag;
|
|
|
-+ tcflag_t c_oflag;
|
|
|
-+ tcflag_t c_cflag;
|
|
|
-+ tcflag_t c_lflag;
|
|
|
-+ cc_t c_line;
|
|
|
-+ cc_t c_cc[NCCS];
|
|
|
-+ speed_t __c_ispeed;
|
|
|
-+ speed_t __c_ospeed;
|
|
|
-+};
|
|
|
-+
|
|
|
-+#define VINTR 0
|
|
|
-+#define VQUIT 1
|
|
|
-+#define VERASE 2
|
|
|
-+#define VKILL 3
|
|
|
-+#define VEOF 4
|
|
|
-+#define VTIME 5
|
|
|
-+#define VMIN 6
|
|
|
-+#define VSWTC 7
|
|
|
-+#define VSTART 8
|
|
|
-+#define VSTOP 9
|
|
|
-+#define VSUSP 10
|
|
|
-+#define VEOL 11
|
|
|
-+#define VREPRINT 12
|
|
|
-+#define VDISCARD 13
|
|
|
-+#define VWERASE 14
|
|
|
-+#define VLNEXT 15
|
|
|
-+#define VEOL2 16
|
|
|
-+
|
|
|
-+#define IGNBRK 0000001
|
|
|
-+#define BRKINT 0000002
|
|
|
-+#define IGNPAR 0000004
|
|
|
-+#define PARMRK 0000010
|
|
|
-+#define INPCK 0000020
|
|
|
-+#define ISTRIP 0000040
|
|
|
-+#define INLCR 0000100
|
|
|
-+#define IGNCR 0000200
|
|
|
-+#define ICRNL 0000400
|
|
|
-+#define IUCLC 0001000
|
|
|
-+#define IXON 0002000
|
|
|
-+#define IXANY 0004000
|
|
|
-+#define IXOFF 0010000
|
|
|
-+#define IMAXBEL 0020000
|
|
|
-+#define IUTF8 0040000
|
|
|
-+
|
|
|
-+#define OPOST 0000001
|
|
|
-+#define OLCUC 0000002
|
|
|
-+#define ONLCR 0000004
|
|
|
-+#define OCRNL 0000010
|
|
|
-+#define ONOCR 0000020
|
|
|
-+#define ONLRET 0000040
|
|
|
-+#define OFILL 0000100
|
|
|
-+#define OFDEL 0000200
|
|
|
-+#define NLDLY 0000400
|
|
|
-+#define NL0 0000000
|
|
|
-+#define NL1 0000400
|
|
|
-+#define CRDLY 0003000
|
|
|
-+#define CR0 0000000
|
|
|
-+#define CR1 0001000
|
|
|
-+#define CR2 0002000
|
|
|
-+#define CR3 0003000
|
|
|
-+#define TABDLY 0014000
|
|
|
-+#define TAB0 0000000
|
|
|
-+#define TAB1 0004000
|
|
|
-+#define TAB2 0010000
|
|
|
-+#define TAB3 0014000
|
|
|
-+#define BSDLY 0020000
|
|
|
-+#define BS0 0000000
|
|
|
-+#define BS1 0020000
|
|
|
-+#define FFDLY 0100000
|
|
|
-+#define FF0 0000000
|
|
|
-+#define FF1 0100000
|
|
|
-+
|
|
|
-+#define VTDLY 0040000
|
|
|
-+#define VT0 0000000
|
|
|
-+#define VT1 0040000
|
|
|
-+
|
|
|
-+#define B0 0000000
|
|
|
-+#define B50 0000001
|
|
|
-+#define B75 0000002
|
|
|
-+#define B110 0000003
|
|
|
-+#define B134 0000004
|
|
|
-+#define B150 0000005
|
|
|
-+#define B200 0000006
|
|
|
-+#define B300 0000007
|
|
|
-+#define B600 0000010
|
|
|
-+#define B1200 0000011
|
|
|
-+#define B1800 0000012
|
|
|
-+#define B2400 0000013
|
|
|
-+#define B4800 0000014
|
|
|
-+#define B9600 0000015
|
|
|
-+#define B19200 0000016
|
|
|
-+#define B38400 0000017
|
|
|
-+
|
|
|
-+#define B57600 0010001
|
|
|
-+#define B115200 0010002
|
|
|
-+#define B230400 0010003
|
|
|
-+#define B460800 0010004
|
|
|
-+#define B500000 0010005
|
|
|
-+#define B576000 0010006
|
|
|
-+#define B921600 0010007
|
|
|
-+#define B1000000 0010010
|
|
|
-+#define B1152000 0010011
|
|
|
-+#define B1500000 0010012
|
|
|
-+#define B2000000 0010013
|
|
|
-+#define B2500000 0010014
|
|
|
-+#define B3000000 0010015
|
|
|
-+#define B3500000 0010016
|
|
|
-+#define B4000000 0010017
|
|
|
-+
|
|
|
-+#define CBAUD 0010017
|
|
|
-+
|
|
|
-+#define CSIZE 0000060
|
|
|
-+#define CS5 0000000
|
|
|
-+#define CS6 0000020
|
|
|
-+#define CS7 0000040
|
|
|
-+#define CS8 0000060
|
|
|
-+#define CSTOPB 0000100
|
|
|
-+#define CREAD 0000200
|
|
|
-+#define PARENB 0000400
|
|
|
-+#define PARODD 0001000
|
|
|
-+#define HUPCL 0002000
|
|
|
-+#define CLOCAL 0004000
|
|
|
-+
|
|
|
-+#define ISIG 0000001
|
|
|
-+#define ICANON 0000002
|
|
|
-+#define ECHO 0000010
|
|
|
-+#define ECHOE 0000020
|
|
|
-+#define ECHOK 0000040
|
|
|
-+#define ECHONL 0000100
|
|
|
-+#define NOFLSH 0000200
|
|
|
-+#define TOSTOP 0000400
|
|
|
-+#define IEXTEN 0100000
|
|
|
-+
|
|
|
-+#define ECHOCTL 0001000
|
|
|
-+#define ECHOPRT 0002000
|
|
|
-+#define ECHOKE 0004000
|
|
|
-+#define FLUSHO 0010000
|
|
|
-+#define PENDIN 0040000
|
|
|
-+
|
|
|
-+#define TCOOFF 0
|
|
|
-+#define TCOON 1
|
|
|
-+#define TCIOFF 2
|
|
|
-+#define TCION 3
|
|
|
-+
|
|
|
-+#define TCIFLUSH 0
|
|
|
-+#define TCOFLUSH 1
|
|
|
-+#define TCIOFLUSH 2
|
|
|
-+
|
|
|
-+#define TCSANOW 0
|
|
|
-+#define TCSADRAIN 1
|
|
|
-+#define TCSAFLUSH 2
|
|
|
-+
|
|
|
-+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
-+#define CBAUDEX 0010000
|
|
|
-+#define CRTSCTS 020000000000
|
|
|
-+#define EXTPROC 0200000
|
|
|
-+#define XTABS 0014000
|
|
|
-+#endif
|
|
|
---- a/arch/i386/atomic.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,110 +0,0 @@
|
|
|
--#ifndef _INTERNAL_ATOMIC_H
|
|
|
--#define _INTERNAL_ATOMIC_H
|
|
|
--
|
|
|
--#include <stdint.h>
|
|
|
--
|
|
|
--static inline int a_ctz_64(uint64_t x)
|
|
|
--{
|
|
|
-- int r;
|
|
|
-- __asm__( "bsf %1,%0 ; jnz 1f ; bsf %2,%0 ; addl $32,%0\n1:"
|
|
|
-- : "=&r"(r) : "r"((unsigned)x), "r"((unsigned)(x>>32)) );
|
|
|
-- return r;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_ctz_l(unsigned long x)
|
|
|
--{
|
|
|
-- long r;
|
|
|
-- __asm__( "bsf %1,%0" : "=r"(r) : "r"(x) );
|
|
|
-- return r;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; andl %1, (%0) ; lock ; andl %2, 4(%0)"
|
|
|
-- : : "r"((long *)p), "r"((unsigned)v), "r"((unsigned)(v>>32)) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; orl %1, (%0) ; lock ; orl %2, 4(%0)"
|
|
|
-- : : "r"((long *)p), "r"((unsigned)v), "r"((unsigned)(v>>32)) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_l(volatile void *p, long v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; orl %1, %0"
|
|
|
-- : "=m"(*(long *)p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
--{
|
|
|
-- __asm__( "lock ; cmpxchg %3, %1"
|
|
|
-- : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
|
|
|
-- return t;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_cas(volatile int *p, int t, int s)
|
|
|
--{
|
|
|
-- __asm__( "lock ; cmpxchg %3, %1"
|
|
|
-- : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
|
|
|
-- return t;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or(volatile int *p, int v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; orl %1, %0"
|
|
|
-- : "=m"(*p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and(volatile int *p, int v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; andl %1, %0"
|
|
|
-- : "=m"(*p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_swap(volatile int *x, int v)
|
|
|
--{
|
|
|
-- __asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
|
|
|
-- return v;
|
|
|
--}
|
|
|
--
|
|
|
--#define a_xchg a_swap
|
|
|
--
|
|
|
--static inline int a_fetch_add(volatile int *x, int v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
|
|
|
-- return v;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_inc(volatile int *x)
|
|
|
--{
|
|
|
-- __asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_dec(volatile int *x)
|
|
|
--{
|
|
|
-- __asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_store(volatile int *p, int x)
|
|
|
--{
|
|
|
-- __asm__( "movl %1, %0 ; lock ; orl $0,(%%esp)" : "=m"(*p) : "r"(x) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_spin()
|
|
|
--{
|
|
|
-- __asm__ __volatile__( "pause" : : : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_barrier()
|
|
|
--{
|
|
|
-- __asm__ __volatile__( "" : : : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_crash()
|
|
|
--{
|
|
|
-- __asm__ __volatile__( "hlt" : : : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--
|
|
|
--#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/i386/atomic_arch.h
|
|
|
-@@ -0,0 +1,101 @@
|
|
|
-+#define a_cas a_cas
|
|
|
-+static inline int a_cas(volatile int *p, int t, int s)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ "lock ; cmpxchg %3, %1"
|
|
|
-+ : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
|
|
|
-+ return t;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_swap a_swap
|
|
|
-+static inline int a_swap(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "xchg %0, %1"
|
|
|
-+ : "=r"(v), "=m"(*p) : "0"(v) : "memory" );
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_fetch_add a_fetch_add
|
|
|
-+static inline int a_fetch_add(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; xadd %0, %1"
|
|
|
-+ : "=r"(v), "=m"(*p) : "0"(v) : "memory" );
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_and a_and
|
|
|
-+static inline void a_and(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; and %1, %0"
|
|
|
-+ : "=m"(*p) : "r"(v) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_or a_or
|
|
|
-+static inline void a_or(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; or %1, %0"
|
|
|
-+ : "=m"(*p) : "r"(v) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_inc a_inc
|
|
|
-+static inline void a_inc(volatile int *p)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; incl %0"
|
|
|
-+ : "=m"(*p) : "m"(*p) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_dec a_dec
|
|
|
-+static inline void a_dec(volatile int *p)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; decl %0"
|
|
|
-+ : "=m"(*p) : "m"(*p) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_store a_store
|
|
|
-+static inline void a_store(volatile int *p, int x)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "mov %1, %0 ; lock ; orl $0,(%%esp)"
|
|
|
-+ : "=m"(*p) : "r"(x) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_barrier a_barrier
|
|
|
-+static inline void a_barrier()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__( "" : : : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_pause a_pause
|
|
|
-+static inline void a_spin()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__( "pause" : : : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_crash a_crash
|
|
|
-+static inline void a_crash()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__( "hlt" : : : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_ctz_64 a_ctz_64
|
|
|
-+static inline int a_ctz_64(uint64_t x)
|
|
|
-+{
|
|
|
-+ int r;
|
|
|
-+ __asm__( "bsf %1,%0 ; jnz 1f ; bsf %2,%0 ; add $32,%0\n1:"
|
|
|
-+ : "=&r"(r) : "r"((unsigned)x), "r"((unsigned)(x>>32)) );
|
|
|
-+ return r;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_ctz_l a_ctz_l
|
|
|
-+static inline int a_ctz_l(unsigned long x)
|
|
|
-+{
|
|
|
-+ long r;
|
|
|
-+ __asm__( "bsf %1,%0" : "=r"(r) : "r"(x) );
|
|
|
-+ return r;
|
|
|
-+}
|
|
|
---- a/arch/i386/bits/alltypes.h.in
|
|
|
-+++ b/arch/i386/bits/alltypes.h.in
|
|
|
-@@ -26,10 +26,12 @@ TYPEDEF long double float_t;
|
|
|
- TYPEDEF long double double_t;
|
|
|
- #endif
|
|
|
-
|
|
|
--#ifdef __cplusplus
|
|
|
--TYPEDEF struct { alignas(8) long long __ll; long double __ld; } max_align_t;
|
|
|
--#else
|
|
|
-+#if !defined(__cplusplus)
|
|
|
- TYPEDEF struct { _Alignas(8) long long __ll; long double __ld; } max_align_t;
|
|
|
-+#elif defined(__GNUC__)
|
|
|
-+TYPEDEF struct { __attribute__((__aligned__(8))) long long __ll; long double __ld; } max_align_t;
|
|
|
-+#else
|
|
|
-+TYPEDEF struct { alignas(8) long long __ll; long double __ld; } max_align_t;
|
|
|
- #endif
|
|
|
-
|
|
|
- TYPEDEF long time_t;
|
|
|
---- a/arch/i386/bits/errno.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,134 +0,0 @@
|
|
|
--#define EPERM 1
|
|
|
--#define ENOENT 2
|
|
|
--#define ESRCH 3
|
|
|
--#define EINTR 4
|
|
|
--#define EIO 5
|
|
|
--#define ENXIO 6
|
|
|
--#define E2BIG 7
|
|
|
--#define ENOEXEC 8
|
|
|
--#define EBADF 9
|
|
|
--#define ECHILD 10
|
|
|
--#define EAGAIN 11
|
|
|
--#define ENOMEM 12
|
|
|
--#define EACCES 13
|
|
|
--#define EFAULT 14
|
|
|
--#define ENOTBLK 15
|
|
|
--#define EBUSY 16
|
|
|
--#define EEXIST 17
|
|
|
--#define EXDEV 18
|
|
|
--#define ENODEV 19
|
|
|
--#define ENOTDIR 20
|
|
|
--#define EISDIR 21
|
|
|
--#define EINVAL 22
|
|
|
--#define ENFILE 23
|
|
|
--#define EMFILE 24
|
|
|
--#define ENOTTY 25
|
|
|
--#define ETXTBSY 26
|
|
|
--#define EFBIG 27
|
|
|
--#define ENOSPC 28
|
|
|
--#define ESPIPE 29
|
|
|
--#define EROFS 30
|
|
|
--#define EMLINK 31
|
|
|
--#define EPIPE 32
|
|
|
--#define EDOM 33
|
|
|
--#define ERANGE 34
|
|
|
--#define EDEADLK 35
|
|
|
--#define ENAMETOOLONG 36
|
|
|
--#define ENOLCK 37
|
|
|
--#define ENOSYS 38
|
|
|
--#define ENOTEMPTY 39
|
|
|
--#define ELOOP 40
|
|
|
--#define EWOULDBLOCK EAGAIN
|
|
|
--#define ENOMSG 42
|
|
|
--#define EIDRM 43
|
|
|
--#define ECHRNG 44
|
|
|
--#define EL2NSYNC 45
|
|
|
--#define EL3HLT 46
|
|
|
--#define EL3RST 47
|
|
|
--#define ELNRNG 48
|
|
|
--#define EUNATCH 49
|
|
|
--#define ENOCSI 50
|
|
|
--#define EL2HLT 51
|
|
|
--#define EBADE 52
|
|
|
--#define EBADR 53
|
|
|
--#define EXFULL 54
|
|
|
--#define ENOANO 55
|
|
|
--#define EBADRQC 56
|
|
|
--#define EBADSLT 57
|
|
|
--#define EDEADLOCK EDEADLK
|
|
|
--#define EBFONT 59
|
|
|
--#define ENOSTR 60
|
|
|
--#define ENODATA 61
|
|
|
--#define ETIME 62
|
|
|
--#define ENOSR 63
|
|
|
--#define ENONET 64
|
|
|
--#define ENOPKG 65
|
|
|
--#define EREMOTE 66
|
|
|
--#define ENOLINK 67
|
|
|
--#define EADV 68
|
|
|
--#define ESRMNT 69
|
|
|
--#define ECOMM 70
|
|
|
--#define EPROTO 71
|
|
|
--#define EMULTIHOP 72
|
|
|
--#define EDOTDOT 73
|
|
|
--#define EBADMSG 74
|
|
|
--#define EOVERFLOW 75
|
|
|
--#define ENOTUNIQ 76
|
|
|
--#define EBADFD 77
|
|
|
--#define EREMCHG 78
|
|
|
--#define ELIBACC 79
|
|
|
--#define ELIBBAD 80
|
|
|
--#define ELIBSCN 81
|
|
|
--#define ELIBMAX 82
|
|
|
--#define ELIBEXEC 83
|
|
|
--#define EILSEQ 84
|
|
|
--#define ERESTART 85
|
|
|
--#define ESTRPIPE 86
|
|
|
--#define EUSERS 87
|
|
|
--#define ENOTSOCK 88
|
|
|
--#define EDESTADDRREQ 89
|
|
|
--#define EMSGSIZE 90
|
|
|
--#define EPROTOTYPE 91
|
|
|
--#define ENOPROTOOPT 92
|
|
|
--#define EPROTONOSUPPORT 93
|
|
|
--#define ESOCKTNOSUPPORT 94
|
|
|
--#define EOPNOTSUPP 95
|
|
|
--#define ENOTSUP EOPNOTSUPP
|
|
|
--#define EPFNOSUPPORT 96
|
|
|
--#define EAFNOSUPPORT 97
|
|
|
--#define EADDRINUSE 98
|
|
|
--#define EADDRNOTAVAIL 99
|
|
|
--#define ENETDOWN 100
|
|
|
--#define ENETUNREACH 101
|
|
|
--#define ENETRESET 102
|
|
|
--#define ECONNABORTED 103
|
|
|
--#define ECONNRESET 104
|
|
|
--#define ENOBUFS 105
|
|
|
--#define EISCONN 106
|
|
|
--#define ENOTCONN 107
|
|
|
--#define ESHUTDOWN 108
|
|
|
--#define ETOOMANYREFS 109
|
|
|
--#define ETIMEDOUT 110
|
|
|
--#define ECONNREFUSED 111
|
|
|
--#define EHOSTDOWN 112
|
|
|
--#define EHOSTUNREACH 113
|
|
|
--#define EALREADY 114
|
|
|
--#define EINPROGRESS 115
|
|
|
--#define ESTALE 116
|
|
|
--#define EUCLEAN 117
|
|
|
--#define ENOTNAM 118
|
|
|
--#define ENAVAIL 119
|
|
|
--#define EISNAM 120
|
|
|
--#define EREMOTEIO 121
|
|
|
--#define EDQUOT 122
|
|
|
--#define ENOMEDIUM 123
|
|
|
--#define EMEDIUMTYPE 124
|
|
|
--#define ECANCELED 125
|
|
|
--#define ENOKEY 126
|
|
|
--#define EKEYEXPIRED 127
|
|
|
--#define EKEYREVOKED 128
|
|
|
--#define EKEYREJECTED 129
|
|
|
--#define EOWNERDEAD 130
|
|
|
--#define ENOTRECOVERABLE 131
|
|
|
--#define ERFKILL 132
|
|
|
--#define EHWPOISON 133
|
|
|
---- a/arch/i386/bits/fcntl.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,40 +0,0 @@
|
|
|
--#define O_CREAT 0100
|
|
|
--#define O_EXCL 0200
|
|
|
--#define O_NOCTTY 0400
|
|
|
--#define O_TRUNC 01000
|
|
|
--#define O_APPEND 02000
|
|
|
--#define O_NONBLOCK 04000
|
|
|
--#define O_DSYNC 010000
|
|
|
--#define O_SYNC 04010000
|
|
|
--#define O_RSYNC 04010000
|
|
|
--#define O_DIRECTORY 0200000
|
|
|
--#define O_NOFOLLOW 0400000
|
|
|
--#define O_CLOEXEC 02000000
|
|
|
--
|
|
|
--#define O_ASYNC 020000
|
|
|
--#define O_DIRECT 040000
|
|
|
--#define O_LARGEFILE 0100000
|
|
|
--#define O_NOATIME 01000000
|
|
|
--#define O_PATH 010000000
|
|
|
--#define O_TMPFILE 020200000
|
|
|
--#define O_NDELAY O_NONBLOCK
|
|
|
--
|
|
|
--#define F_DUPFD 0
|
|
|
--#define F_GETFD 1
|
|
|
--#define F_SETFD 2
|
|
|
--#define F_GETFL 3
|
|
|
--#define F_SETFL 4
|
|
|
--
|
|
|
--#define F_SETOWN 8
|
|
|
--#define F_GETOWN 9
|
|
|
--#define F_SETSIG 10
|
|
|
--#define F_GETSIG 11
|
|
|
--
|
|
|
--#define F_GETLK 12
|
|
|
--#define F_SETLK 13
|
|
|
--#define F_SETLKW 14
|
|
|
--
|
|
|
--#define F_SETOWN_EX 15
|
|
|
--#define F_GETOWN_EX 16
|
|
|
--
|
|
|
--#define F_GETOWNER_UIDS 17
|
|
|
---- a/arch/i386/bits/ioctl.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,197 +0,0 @@
|
|
|
--#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
|
|
|
--#define _IOC_NONE 0U
|
|
|
--#define _IOC_WRITE 1U
|
|
|
--#define _IOC_READ 2U
|
|
|
--
|
|
|
--#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
|
|
|
--#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
|
|
|
--#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
|
|
|
--#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
|
|
|
--
|
|
|
--#define TCGETS 0x5401
|
|
|
--#define TCSETS 0x5402
|
|
|
--#define TCSETSW 0x5403
|
|
|
--#define TCSETSF 0x5404
|
|
|
--#define TCGETA 0x5405
|
|
|
--#define TCSETA 0x5406
|
|
|
--#define TCSETAW 0x5407
|
|
|
--#define TCSETAF 0x5408
|
|
|
--#define TCSBRK 0x5409
|
|
|
--#define TCXONC 0x540A
|
|
|
--#define TCFLSH 0x540B
|
|
|
--#define TIOCEXCL 0x540C
|
|
|
--#define TIOCNXCL 0x540D
|
|
|
--#define TIOCSCTTY 0x540E
|
|
|
--#define TIOCGPGRP 0x540F
|
|
|
--#define TIOCSPGRP 0x5410
|
|
|
--#define TIOCOUTQ 0x5411
|
|
|
--#define TIOCSTI 0x5412
|
|
|
--#define TIOCGWINSZ 0x5413
|
|
|
--#define TIOCSWINSZ 0x5414
|
|
|
--#define TIOCMGET 0x5415
|
|
|
--#define TIOCMBIS 0x5416
|
|
|
--#define TIOCMBIC 0x5417
|
|
|
--#define TIOCMSET 0x5418
|
|
|
--#define TIOCGSOFTCAR 0x5419
|
|
|
--#define TIOCSSOFTCAR 0x541A
|
|
|
--#define FIONREAD 0x541B
|
|
|
--#define TIOCINQ FIONREAD
|
|
|
--#define TIOCLINUX 0x541C
|
|
|
--#define TIOCCONS 0x541D
|
|
|
--#define TIOCGSERIAL 0x541E
|
|
|
--#define TIOCSSERIAL 0x541F
|
|
|
--#define TIOCPKT 0x5420
|
|
|
--#define FIONBIO 0x5421
|
|
|
--#define TIOCNOTTY 0x5422
|
|
|
--#define TIOCSETD 0x5423
|
|
|
--#define TIOCGETD 0x5424
|
|
|
--#define TCSBRKP 0x5425
|
|
|
--#define TIOCTTYGSTRUCT 0x5426
|
|
|
--#define TIOCSBRK 0x5427
|
|
|
--#define TIOCCBRK 0x5428
|
|
|
--#define TIOCGSID 0x5429
|
|
|
--#define TIOCGPTN 0x80045430
|
|
|
--#define TIOCSPTLCK 0x40045431
|
|
|
--#define TCGETX 0x5432
|
|
|
--#define TCSETX 0x5433
|
|
|
--#define TCSETXF 0x5434
|
|
|
--#define TCSETXW 0x5435
|
|
|
--
|
|
|
--#define FIONCLEX 0x5450
|
|
|
--#define FIOCLEX 0x5451
|
|
|
--#define FIOASYNC 0x5452
|
|
|
--#define TIOCSERCONFIG 0x5453
|
|
|
--#define TIOCSERGWILD 0x5454
|
|
|
--#define TIOCSERSWILD 0x5455
|
|
|
--#define TIOCGLCKTRMIOS 0x5456
|
|
|
--#define TIOCSLCKTRMIOS 0x5457
|
|
|
--#define TIOCSERGSTRUCT 0x5458
|
|
|
--#define TIOCSERGETLSR 0x5459
|
|
|
--#define TIOCSERGETMULTI 0x545A
|
|
|
--#define TIOCSERSETMULTI 0x545B
|
|
|
--
|
|
|
--#define TIOCMIWAIT 0x545C
|
|
|
--#define TIOCGICOUNT 0x545D
|
|
|
--#define TIOCGHAYESESP 0x545E
|
|
|
--#define TIOCSHAYESESP 0x545F
|
|
|
--#define FIOQSIZE 0x5460
|
|
|
--
|
|
|
--#define TIOCPKT_DATA 0
|
|
|
--#define TIOCPKT_FLUSHREAD 1
|
|
|
--#define TIOCPKT_FLUSHWRITE 2
|
|
|
--#define TIOCPKT_STOP 4
|
|
|
--#define TIOCPKT_START 8
|
|
|
--#define TIOCPKT_NOSTOP 16
|
|
|
--#define TIOCPKT_DOSTOP 32
|
|
|
--#define TIOCPKT_IOCTL 64
|
|
|
--
|
|
|
--#define TIOCSER_TEMT 0x01
|
|
|
--
|
|
|
--struct winsize {
|
|
|
-- unsigned short ws_row;
|
|
|
-- unsigned short ws_col;
|
|
|
-- unsigned short ws_xpixel;
|
|
|
-- unsigned short ws_ypixel;
|
|
|
--};
|
|
|
--
|
|
|
--#define TIOCM_LE 0x001
|
|
|
--#define TIOCM_DTR 0x002
|
|
|
--#define TIOCM_RTS 0x004
|
|
|
--#define TIOCM_ST 0x008
|
|
|
--#define TIOCM_SR 0x010
|
|
|
--#define TIOCM_CTS 0x020
|
|
|
--#define TIOCM_CAR 0x040
|
|
|
--#define TIOCM_RNG 0x080
|
|
|
--#define TIOCM_DSR 0x100
|
|
|
--#define TIOCM_CD TIOCM_CAR
|
|
|
--#define TIOCM_RI TIOCM_RNG
|
|
|
--#define TIOCM_OUT1 0x2000
|
|
|
--#define TIOCM_OUT2 0x4000
|
|
|
--#define TIOCM_LOOP 0x8000
|
|
|
--#define TIOCM_MODEM_BITS TIOCM_OUT2
|
|
|
--
|
|
|
--#define N_TTY 0
|
|
|
--#define N_SLIP 1
|
|
|
--#define N_MOUSE 2
|
|
|
--#define N_PPP 3
|
|
|
--#define N_STRIP 4
|
|
|
--#define N_AX25 5
|
|
|
--#define N_X25 6
|
|
|
--#define N_6PACK 7
|
|
|
--#define N_MASC 8
|
|
|
--#define N_R3964 9
|
|
|
--#define N_PROFIBUS_FDL 10
|
|
|
--#define N_IRDA 11
|
|
|
--#define N_SMSBLOCK 12
|
|
|
--#define N_HDLC 13
|
|
|
--#define N_SYNC_PPP 14
|
|
|
--#define N_HCI 15
|
|
|
--
|
|
|
--#define FIOSETOWN 0x8901
|
|
|
--#define SIOCSPGRP 0x8902
|
|
|
--#define FIOGETOWN 0x8903
|
|
|
--#define SIOCGPGRP 0x8904
|
|
|
--#define SIOCATMARK 0x8905
|
|
|
--#define SIOCGSTAMP 0x8906
|
|
|
--
|
|
|
--#define SIOCADDRT 0x890B
|
|
|
--#define SIOCDELRT 0x890C
|
|
|
--#define SIOCRTMSG 0x890D
|
|
|
--
|
|
|
--#define SIOCGIFNAME 0x8910
|
|
|
--#define SIOCSIFLINK 0x8911
|
|
|
--#define SIOCGIFCONF 0x8912
|
|
|
--#define SIOCGIFFLAGS 0x8913
|
|
|
--#define SIOCSIFFLAGS 0x8914
|
|
|
--#define SIOCGIFADDR 0x8915
|
|
|
--#define SIOCSIFADDR 0x8916
|
|
|
--#define SIOCGIFDSTADDR 0x8917
|
|
|
--#define SIOCSIFDSTADDR 0x8918
|
|
|
--#define SIOCGIFBRDADDR 0x8919
|
|
|
--#define SIOCSIFBRDADDR 0x891a
|
|
|
--#define SIOCGIFNETMASK 0x891b
|
|
|
--#define SIOCSIFNETMASK 0x891c
|
|
|
--#define SIOCGIFMETRIC 0x891d
|
|
|
--#define SIOCSIFMETRIC 0x891e
|
|
|
--#define SIOCGIFMEM 0x891f
|
|
|
--#define SIOCSIFMEM 0x8920
|
|
|
--#define SIOCGIFMTU 0x8921
|
|
|
--#define SIOCSIFMTU 0x8922
|
|
|
--#define SIOCSIFHWADDR 0x8924
|
|
|
--#define SIOCGIFENCAP 0x8925
|
|
|
--#define SIOCSIFENCAP 0x8926
|
|
|
--#define SIOCGIFHWADDR 0x8927
|
|
|
--#define SIOCGIFSLAVE 0x8929
|
|
|
--#define SIOCSIFSLAVE 0x8930
|
|
|
--#define SIOCADDMULTI 0x8931
|
|
|
--#define SIOCDELMULTI 0x8932
|
|
|
--#define SIOCGIFINDEX 0x8933
|
|
|
--#define SIOGIFINDEX SIOCGIFINDEX
|
|
|
--#define SIOCSIFPFLAGS 0x8934
|
|
|
--#define SIOCGIFPFLAGS 0x8935
|
|
|
--#define SIOCDIFADDR 0x8936
|
|
|
--#define SIOCSIFHWBROADCAST 0x8937
|
|
|
--#define SIOCGIFCOUNT 0x8938
|
|
|
--
|
|
|
--#define SIOCGIFBR 0x8940
|
|
|
--#define SIOCSIFBR 0x8941
|
|
|
--
|
|
|
--#define SIOCGIFTXQLEN 0x8942
|
|
|
--#define SIOCSIFTXQLEN 0x8943
|
|
|
--
|
|
|
--#define SIOCDARP 0x8953
|
|
|
--#define SIOCGARP 0x8954
|
|
|
--#define SIOCSARP 0x8955
|
|
|
--
|
|
|
--#define SIOCDRARP 0x8960
|
|
|
--#define SIOCGRARP 0x8961
|
|
|
--#define SIOCSRARP 0x8962
|
|
|
--
|
|
|
--#define SIOCGIFMAP 0x8970
|
|
|
--#define SIOCSIFMAP 0x8971
|
|
|
--
|
|
|
--#define SIOCADDDLCI 0x8980
|
|
|
--#define SIOCDELDLCI 0x8981
|
|
|
--
|
|
|
--#define SIOCDEVPRIVATE 0x89F0
|
|
|
--#define SIOCPROTOPRIVATE 0x89E0
|
|
|
---- a/arch/i386/bits/ipc.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,14 +0,0 @@
|
|
|
--struct ipc_perm
|
|
|
--{
|
|
|
-- key_t __ipc_perm_key;
|
|
|
-- uid_t uid;
|
|
|
-- gid_t gid;
|
|
|
-- uid_t cuid;
|
|
|
-- gid_t cgid;
|
|
|
-- mode_t mode;
|
|
|
-- int __ipc_perm_seq;
|
|
|
-- long __pad1;
|
|
|
-- long __pad2;
|
|
|
--};
|
|
|
--
|
|
|
--#define IPC_64 0x100
|
|
|
---- a/arch/i386/bits/mman.h
|
|
|
-+++ b/arch/i386/bits/mman.h
|
|
|
-@@ -38,6 +38,7 @@
|
|
|
-
|
|
|
- #define MCL_CURRENT 1
|
|
|
- #define MCL_FUTURE 2
|
|
|
-+#define MCL_ONFAULT 4
|
|
|
-
|
|
|
- #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
- #define MADV_NORMAL 0
|
|
|
---- a/arch/i386/bits/msg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,16 +0,0 @@
|
|
|
--struct msqid_ds
|
|
|
--{
|
|
|
-- struct ipc_perm msg_perm;
|
|
|
-- time_t msg_stime;
|
|
|
-- int __unused1;
|
|
|
-- time_t msg_rtime;
|
|
|
-- int __unused2;
|
|
|
-- time_t msg_ctime;
|
|
|
-- int __unused3;
|
|
|
-- unsigned long msg_cbytes;
|
|
|
-- msgqnum_t msg_qnum;
|
|
|
-- msglen_t msg_qbytes;
|
|
|
-- pid_t msg_lspid;
|
|
|
-- pid_t msg_lrpid;
|
|
|
-- unsigned long __unused[2];
|
|
|
--};
|
|
|
---- a/arch/i386/bits/sem.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,16 +0,0 @@
|
|
|
--struct semid_ds {
|
|
|
-- struct ipc_perm sem_perm;
|
|
|
-- time_t sem_otime;
|
|
|
-- time_t __unused1;
|
|
|
-- time_t sem_ctime;
|
|
|
-- time_t __unused2;
|
|
|
--#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
-- unsigned short sem_nsems;
|
|
|
-- char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
--#else
|
|
|
-- char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
-- unsigned short sem_nsems;
|
|
|
--#endif
|
|
|
-- time_t __unused3;
|
|
|
-- time_t __unused4;
|
|
|
--};
|
|
|
---- a/arch/i386/bits/shm.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,29 +0,0 @@
|
|
|
--#define SHMLBA 4096
|
|
|
--
|
|
|
--struct shmid_ds
|
|
|
--{
|
|
|
-- struct ipc_perm shm_perm;
|
|
|
-- size_t shm_segsz;
|
|
|
-- time_t shm_atime;
|
|
|
-- int __unused1;
|
|
|
-- time_t shm_dtime;
|
|
|
-- int __unused2;
|
|
|
-- time_t shm_ctime;
|
|
|
-- int __unused3;
|
|
|
-- pid_t shm_cpid;
|
|
|
-- pid_t shm_lpid;
|
|
|
-- unsigned long shm_nattch;
|
|
|
-- unsigned long __pad1;
|
|
|
-- unsigned long __pad2;
|
|
|
--};
|
|
|
--
|
|
|
--struct shminfo {
|
|
|
-- unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
|
|
|
--};
|
|
|
--
|
|
|
--struct shm_info {
|
|
|
-- int __used_ids;
|
|
|
-- unsigned long shm_tot, shm_rss, shm_swp;
|
|
|
-- unsigned long __swap_attempts, __swap_successes;
|
|
|
--};
|
|
|
--
|
|
|
---- a/arch/i386/bits/socket.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,17 +0,0 @@
|
|
|
--struct msghdr
|
|
|
--{
|
|
|
-- void *msg_name;
|
|
|
-- socklen_t msg_namelen;
|
|
|
-- struct iovec *msg_iov;
|
|
|
-- int msg_iovlen;
|
|
|
-- void *msg_control;
|
|
|
-- socklen_t msg_controllen;
|
|
|
-- int msg_flags;
|
|
|
--};
|
|
|
--
|
|
|
--struct cmsghdr
|
|
|
--{
|
|
|
-- socklen_t cmsg_len;
|
|
|
-- int cmsg_level;
|
|
|
-- int cmsg_type;
|
|
|
--};
|
|
|
---- a/arch/i386/bits/statfs.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,7 +0,0 @@
|
|
|
--struct statfs {
|
|
|
-- unsigned long f_type, f_bsize;
|
|
|
-- fsblkcnt_t f_blocks, f_bfree, f_bavail;
|
|
|
-- fsfilcnt_t f_files, f_ffree;
|
|
|
-- fsid_t f_fsid;
|
|
|
-- unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
|
|
|
--};
|
|
|
---- a/arch/i386/bits/syscall.h
|
|
|
-+++ b/arch/i386/bits/syscall.h
|
|
|
-@@ -357,6 +357,24 @@
|
|
|
- #define __NR_memfd_create 356
|
|
|
- #define __NR_bpf 357
|
|
|
- #define __NR_execveat 358
|
|
|
-+#define __NR_socket 359
|
|
|
-+#define __NR_socketpair 360
|
|
|
-+#define __NR_bind 361
|
|
|
-+#define __NR_connect 362
|
|
|
-+#define __NR_listen 363
|
|
|
-+#define __NR_accept4 364
|
|
|
-+#define __NR_getsockopt 365
|
|
|
-+#define __NR_setsockopt 366
|
|
|
-+#define __NR_getsockname 367
|
|
|
-+#define __NR_getpeername 368
|
|
|
-+#define __NR_sendto 369
|
|
|
-+#define __NR_sendmsg 370
|
|
|
-+#define __NR_recvfrom 371
|
|
|
-+#define __NR_recvmsg 372
|
|
|
-+#define __NR_shutdown 373
|
|
|
-+#define __NR_userfaultfd 374
|
|
|
-+#define __NR_membarrier 375
|
|
|
-+#define __NR_mlock2 376
|
|
|
-
|
|
|
-
|
|
|
- /* Repeated with SYS_ prefix */
|
|
|
-@@ -720,3 +738,21 @@
|
|
|
- #define SYS_memfd_create 356
|
|
|
- #define SYS_bpf 357
|
|
|
- #define SYS_execveat 358
|
|
|
-+#define SYS_socket 359
|
|
|
-+#define SYS_socketpair 360
|
|
|
-+#define SYS_bind 361
|
|
|
-+#define SYS_connect 362
|
|
|
-+#define SYS_listen 363
|
|
|
-+#define SYS_accept4 364
|
|
|
-+#define SYS_getsockopt 365
|
|
|
-+#define SYS_setsockopt 366
|
|
|
-+#define SYS_getsockname 367
|
|
|
-+#define SYS_getpeername 368
|
|
|
-+#define SYS_sendto 369
|
|
|
-+#define SYS_sendmsg 370
|
|
|
-+#define SYS_recvfrom 371
|
|
|
-+#define SYS_recvmsg 372
|
|
|
-+#define SYS_shutdown 373
|
|
|
-+#define SYS_userfaultfd 374
|
|
|
-+#define SYS_membarrier 375
|
|
|
-+#define SYS_mlock2 376
|
|
|
---- a/arch/i386/bits/termios.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,160 +0,0 @@
|
|
|
--struct termios
|
|
|
--{
|
|
|
-- tcflag_t c_iflag;
|
|
|
-- tcflag_t c_oflag;
|
|
|
-- tcflag_t c_cflag;
|
|
|
-- tcflag_t c_lflag;
|
|
|
-- cc_t c_line;
|
|
|
-- cc_t c_cc[NCCS];
|
|
|
-- speed_t __c_ispeed;
|
|
|
-- speed_t __c_ospeed;
|
|
|
--};
|
|
|
--
|
|
|
--#define VINTR 0
|
|
|
--#define VQUIT 1
|
|
|
--#define VERASE 2
|
|
|
--#define VKILL 3
|
|
|
--#define VEOF 4
|
|
|
--#define VTIME 5
|
|
|
--#define VMIN 6
|
|
|
--#define VSWTC 7
|
|
|
--#define VSTART 8
|
|
|
--#define VSTOP 9
|
|
|
--#define VSUSP 10
|
|
|
--#define VEOL 11
|
|
|
--#define VREPRINT 12
|
|
|
--#define VDISCARD 13
|
|
|
--#define VWERASE 14
|
|
|
--#define VLNEXT 15
|
|
|
--#define VEOL2 16
|
|
|
--
|
|
|
--#define IGNBRK 0000001
|
|
|
--#define BRKINT 0000002
|
|
|
--#define IGNPAR 0000004
|
|
|
--#define PARMRK 0000010
|
|
|
--#define INPCK 0000020
|
|
|
--#define ISTRIP 0000040
|
|
|
--#define INLCR 0000100
|
|
|
--#define IGNCR 0000200
|
|
|
--#define ICRNL 0000400
|
|
|
--#define IUCLC 0001000
|
|
|
--#define IXON 0002000
|
|
|
--#define IXANY 0004000
|
|
|
--#define IXOFF 0010000
|
|
|
--#define IMAXBEL 0020000
|
|
|
--#define IUTF8 0040000
|
|
|
--
|
|
|
--#define OPOST 0000001
|
|
|
--#define OLCUC 0000002
|
|
|
--#define ONLCR 0000004
|
|
|
--#define OCRNL 0000010
|
|
|
--#define ONOCR 0000020
|
|
|
--#define ONLRET 0000040
|
|
|
--#define OFILL 0000100
|
|
|
--#define OFDEL 0000200
|
|
|
--#define NLDLY 0000400
|
|
|
--#define NL0 0000000
|
|
|
--#define NL1 0000400
|
|
|
--#define CRDLY 0003000
|
|
|
--#define CR0 0000000
|
|
|
--#define CR1 0001000
|
|
|
--#define CR2 0002000
|
|
|
--#define CR3 0003000
|
|
|
--#define TABDLY 0014000
|
|
|
--#define TAB0 0000000
|
|
|
--#define TAB1 0004000
|
|
|
--#define TAB2 0010000
|
|
|
--#define TAB3 0014000
|
|
|
--#define BSDLY 0020000
|
|
|
--#define BS0 0000000
|
|
|
--#define BS1 0020000
|
|
|
--#define FFDLY 0100000
|
|
|
--#define FF0 0000000
|
|
|
--#define FF1 0100000
|
|
|
--
|
|
|
--#define VTDLY 0040000
|
|
|
--#define VT0 0000000
|
|
|
--#define VT1 0040000
|
|
|
--
|
|
|
--#define B0 0000000
|
|
|
--#define B50 0000001
|
|
|
--#define B75 0000002
|
|
|
--#define B110 0000003
|
|
|
--#define B134 0000004
|
|
|
--#define B150 0000005
|
|
|
--#define B200 0000006
|
|
|
--#define B300 0000007
|
|
|
--#define B600 0000010
|
|
|
--#define B1200 0000011
|
|
|
--#define B1800 0000012
|
|
|
--#define B2400 0000013
|
|
|
--#define B4800 0000014
|
|
|
--#define B9600 0000015
|
|
|
--#define B19200 0000016
|
|
|
--#define B38400 0000017
|
|
|
--
|
|
|
--#define B57600 0010001
|
|
|
--#define B115200 0010002
|
|
|
--#define B230400 0010003
|
|
|
--#define B460800 0010004
|
|
|
--#define B500000 0010005
|
|
|
--#define B576000 0010006
|
|
|
--#define B921600 0010007
|
|
|
--#define B1000000 0010010
|
|
|
--#define B1152000 0010011
|
|
|
--#define B1500000 0010012
|
|
|
--#define B2000000 0010013
|
|
|
--#define B2500000 0010014
|
|
|
--#define B3000000 0010015
|
|
|
--#define B3500000 0010016
|
|
|
--#define B4000000 0010017
|
|
|
--
|
|
|
--#define CBAUD 0010017
|
|
|
--
|
|
|
--#define CSIZE 0000060
|
|
|
--#define CS5 0000000
|
|
|
--#define CS6 0000020
|
|
|
--#define CS7 0000040
|
|
|
--#define CS8 0000060
|
|
|
--#define CSTOPB 0000100
|
|
|
--#define CREAD 0000200
|
|
|
--#define PARENB 0000400
|
|
|
--#define PARODD 0001000
|
|
|
--#define HUPCL 0002000
|
|
|
--#define CLOCAL 0004000
|
|
|
--
|
|
|
--#define ISIG 0000001
|
|
|
--#define ICANON 0000002
|
|
|
--#define ECHO 0000010
|
|
|
--#define ECHOE 0000020
|
|
|
--#define ECHOK 0000040
|
|
|
--#define ECHONL 0000100
|
|
|
--#define NOFLSH 0000200
|
|
|
--#define TOSTOP 0000400
|
|
|
--#define IEXTEN 0100000
|
|
|
--
|
|
|
--#define ECHOCTL 0001000
|
|
|
--#define ECHOPRT 0002000
|
|
|
--#define ECHOKE 0004000
|
|
|
--#define FLUSHO 0010000
|
|
|
--#define PENDIN 0040000
|
|
|
--
|
|
|
--#define TCOOFF 0
|
|
|
--#define TCOON 1
|
|
|
--#define TCIOFF 2
|
|
|
--#define TCION 3
|
|
|
--
|
|
|
--#define TCIFLUSH 0
|
|
|
--#define TCOFLUSH 1
|
|
|
--#define TCIOFLUSH 2
|
|
|
--
|
|
|
--#define TCSANOW 0
|
|
|
--#define TCSADRAIN 1
|
|
|
--#define TCSAFLUSH 2
|
|
|
--
|
|
|
--#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
--#define CBAUDEX 0010000
|
|
|
--#define CRTSCTS 020000000000
|
|
|
--#define EXTPROC 0200000
|
|
|
--#define XTABS 0014000
|
|
|
--#endif
|
|
|
---- a/arch/i386/pthread_arch.h
|
|
|
-+++ b/arch/i386/pthread_arch.h
|
|
|
-@@ -7,4 +7,4 @@ static inline struct pthread *__pthread_
|
|
|
-
|
|
|
- #define TP_ADJ(p) (p)
|
|
|
-
|
|
|
--#define CANCEL_REG_IP 14
|
|
|
-+#define MC_PC gregs[REG_EIP]
|
|
|
---- a/arch/i386/syscall_arch.h
|
|
|
-+++ b/arch/i386/syscall_arch.h
|
|
|
-@@ -55,3 +55,5 @@ static inline long __syscall6(long n, lo
|
|
|
- #define VDSO_USEFUL
|
|
|
- #define VDSO_CGT_SYM "__vdso_clock_gettime"
|
|
|
- #define VDSO_CGT_VER "LINUX_2.6"
|
|
|
-+
|
|
|
-+#define SYSCALL_USE_SOCKETCALL
|
|
|
---- a/arch/microblaze/atomic.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,143 +0,0 @@
|
|
|
--#ifndef _INTERNAL_ATOMIC_H
|
|
|
--#define _INTERNAL_ATOMIC_H
|
|
|
--
|
|
|
--#include <stdint.h>
|
|
|
--
|
|
|
--static inline int a_ctz_l(unsigned long x)
|
|
|
--{
|
|
|
-- static const char debruijn32[32] = {
|
|
|
-- 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
|
|
|
-- 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
|
|
|
-- };
|
|
|
-- return debruijn32[(x&-x)*0x076be629 >> 27];
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_ctz_64(uint64_t x)
|
|
|
--{
|
|
|
-- uint32_t y = x;
|
|
|
-- if (!y) {
|
|
|
-- y = x>>32;
|
|
|
-- return 32 + a_ctz_l(y);
|
|
|
-- }
|
|
|
-- return a_ctz_l(y);
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_cas(volatile int *p, int t, int s)
|
|
|
--{
|
|
|
-- register int old, tmp;
|
|
|
-- __asm__ __volatile__ (
|
|
|
-- " addi %0, r0, 0\n"
|
|
|
-- "1: lwx %0, %2, r0\n"
|
|
|
-- " rsubk %1, %0, %3\n"
|
|
|
-- " bnei %1, 1f\n"
|
|
|
-- " swx %4, %2, r0\n"
|
|
|
-- " addic %1, r0, 0\n"
|
|
|
-- " bnei %1, 1b\n"
|
|
|
-- "1: "
|
|
|
-- : "=&r"(old), "=&r"(tmp)
|
|
|
-- : "r"(p), "r"(t), "r"(s)
|
|
|
-- : "cc", "memory" );
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
--{
|
|
|
-- return (void *)a_cas(p, (int)t, (int)s);
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_swap(volatile int *x, int v)
|
|
|
--{
|
|
|
-- register int old, tmp;
|
|
|
-- __asm__ __volatile__ (
|
|
|
-- " addi %0, r0, 0\n"
|
|
|
-- "1: lwx %0, %2, r0\n"
|
|
|
-- " swx %3, %2, r0\n"
|
|
|
-- " addic %1, r0, 0\n"
|
|
|
-- " bnei %1, 1b\n"
|
|
|
-- "1: "
|
|
|
-- : "=&r"(old), "=&r"(tmp)
|
|
|
-- : "r"(x), "r"(v)
|
|
|
-- : "cc", "memory" );
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_fetch_add(volatile int *x, int v)
|
|
|
--{
|
|
|
-- register int new, tmp;
|
|
|
-- __asm__ __volatile__ (
|
|
|
-- " addi %0, r0, 0\n"
|
|
|
-- "1: lwx %0, %2, r0\n"
|
|
|
-- " addk %0, %0, %3\n"
|
|
|
-- " swx %0, %2, r0\n"
|
|
|
-- " addic %1, r0, 0\n"
|
|
|
-- " bnei %1, 1b\n"
|
|
|
-- "1: "
|
|
|
-- : "=&r"(new), "=&r"(tmp)
|
|
|
-- : "r"(x), "r"(v)
|
|
|
-- : "cc", "memory" );
|
|
|
-- return new-v;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_inc(volatile int *x)
|
|
|
--{
|
|
|
-- a_fetch_add(x, 1);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_dec(volatile int *x)
|
|
|
--{
|
|
|
-- a_fetch_add(x, -1);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_store(volatile int *p, int x)
|
|
|
--{
|
|
|
-- __asm__ __volatile__ (
|
|
|
-- "swi %1, %0"
|
|
|
-- : "=m"(*p) : "r"(x) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--#define a_spin a_barrier
|
|
|
--
|
|
|
--static inline void a_barrier()
|
|
|
--{
|
|
|
-- a_cas(&(int){0}, 0, 0);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_crash()
|
|
|
--{
|
|
|
-- *(volatile char *)0=0;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and(volatile int *p, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *p;
|
|
|
-- while (a_cas(p, old, old&v) != old);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or(volatile int *p, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *p;
|
|
|
-- while (a_cas(p, old, old|v) != old);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_l(volatile void *p, long v)
|
|
|
--{
|
|
|
-- a_or(p, v);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-- a_and((int *)p, u.r[0]);
|
|
|
-- a_and((int *)p+1, u.r[1]);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-- a_or((int *)p, u.r[0]);
|
|
|
-- a_or((int *)p+1, u.r[1]);
|
|
|
--}
|
|
|
--
|
|
|
--#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/microblaze/atomic_arch.h
|
|
|
-@@ -0,0 +1,53 @@
|
|
|
-+#define a_cas a_cas
|
|
|
-+static inline int a_cas(volatile int *p, int t, int s)
|
|
|
-+{
|
|
|
-+ register int old, tmp;
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ " addi %0, r0, 0\n"
|
|
|
-+ "1: lwx %0, %2, r0\n"
|
|
|
-+ " rsubk %1, %0, %3\n"
|
|
|
-+ " bnei %1, 1f\n"
|
|
|
-+ " swx %4, %2, r0\n"
|
|
|
-+ " addic %1, r0, 0\n"
|
|
|
-+ " bnei %1, 1b\n"
|
|
|
-+ "1: "
|
|
|
-+ : "=&r"(old), "=&r"(tmp)
|
|
|
-+ : "r"(p), "r"(t), "r"(s)
|
|
|
-+ : "cc", "memory" );
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_swap a_swap
|
|
|
-+static inline int a_swap(volatile int *x, int v)
|
|
|
-+{
|
|
|
-+ register int old, tmp;
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ " addi %0, r0, 0\n"
|
|
|
-+ "1: lwx %0, %2, r0\n"
|
|
|
-+ " swx %3, %2, r0\n"
|
|
|
-+ " addic %1, r0, 0\n"
|
|
|
-+ " bnei %1, 1b\n"
|
|
|
-+ "1: "
|
|
|
-+ : "=&r"(old), "=&r"(tmp)
|
|
|
-+ : "r"(x), "r"(v)
|
|
|
-+ : "cc", "memory" );
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_fetch_add a_fetch_add
|
|
|
-+static inline int a_fetch_add(volatile int *x, int v)
|
|
|
-+{
|
|
|
-+ register int new, tmp;
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ " addi %0, r0, 0\n"
|
|
|
-+ "1: lwx %0, %2, r0\n"
|
|
|
-+ " addk %0, %0, %3\n"
|
|
|
-+ " swx %0, %2, r0\n"
|
|
|
-+ " addic %1, r0, 0\n"
|
|
|
-+ " bnei %1, 1b\n"
|
|
|
-+ "1: "
|
|
|
-+ : "=&r"(new), "=&r"(tmp)
|
|
|
-+ : "r"(x), "r"(v)
|
|
|
-+ : "cc", "memory" );
|
|
|
-+ return new-v;
|
|
|
-+}
|
|
|
---- a/arch/microblaze/bits/errno.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,134 +0,0 @@
|
|
|
--#define EPERM 1
|
|
|
--#define ENOENT 2
|
|
|
--#define ESRCH 3
|
|
|
--#define EINTR 4
|
|
|
--#define EIO 5
|
|
|
--#define ENXIO 6
|
|
|
--#define E2BIG 7
|
|
|
--#define ENOEXEC 8
|
|
|
--#define EBADF 9
|
|
|
--#define ECHILD 10
|
|
|
--#define EAGAIN 11
|
|
|
--#define ENOMEM 12
|
|
|
--#define EACCES 13
|
|
|
--#define EFAULT 14
|
|
|
--#define ENOTBLK 15
|
|
|
--#define EBUSY 16
|
|
|
--#define EEXIST 17
|
|
|
--#define EXDEV 18
|
|
|
--#define ENODEV 19
|
|
|
--#define ENOTDIR 20
|
|
|
--#define EISDIR 21
|
|
|
--#define EINVAL 22
|
|
|
--#define ENFILE 23
|
|
|
--#define EMFILE 24
|
|
|
--#define ENOTTY 25
|
|
|
--#define ETXTBSY 26
|
|
|
--#define EFBIG 27
|
|
|
--#define ENOSPC 28
|
|
|
--#define ESPIPE 29
|
|
|
--#define EROFS 30
|
|
|
--#define EMLINK 31
|
|
|
--#define EPIPE 32
|
|
|
--#define EDOM 33
|
|
|
--#define ERANGE 34
|
|
|
--#define EDEADLK 35
|
|
|
--#define ENAMETOOLONG 36
|
|
|
--#define ENOLCK 37
|
|
|
--#define ENOSYS 38
|
|
|
--#define ENOTEMPTY 39
|
|
|
--#define ELOOP 40
|
|
|
--#define EWOULDBLOCK EAGAIN
|
|
|
--#define ENOMSG 42
|
|
|
--#define EIDRM 43
|
|
|
--#define ECHRNG 44
|
|
|
--#define EL2NSYNC 45
|
|
|
--#define EL3HLT 46
|
|
|
--#define EL3RST 47
|
|
|
--#define ELNRNG 48
|
|
|
--#define EUNATCH 49
|
|
|
--#define ENOCSI 50
|
|
|
--#define EL2HLT 51
|
|
|
--#define EBADE 52
|
|
|
--#define EBADR 53
|
|
|
--#define EXFULL 54
|
|
|
--#define ENOANO 55
|
|
|
--#define EBADRQC 56
|
|
|
--#define EBADSLT 57
|
|
|
--#define EDEADLOCK EDEADLK
|
|
|
--#define EBFONT 59
|
|
|
--#define ENOSTR 60
|
|
|
--#define ENODATA 61
|
|
|
--#define ETIME 62
|
|
|
--#define ENOSR 63
|
|
|
--#define ENONET 64
|
|
|
--#define ENOPKG 65
|
|
|
--#define EREMOTE 66
|
|
|
--#define ENOLINK 67
|
|
|
--#define EADV 68
|
|
|
--#define ESRMNT 69
|
|
|
--#define ECOMM 70
|
|
|
--#define EPROTO 71
|
|
|
--#define EMULTIHOP 72
|
|
|
--#define EDOTDOT 73
|
|
|
--#define EBADMSG 74
|
|
|
--#define EOVERFLOW 75
|
|
|
--#define ENOTUNIQ 76
|
|
|
--#define EBADFD 77
|
|
|
--#define EREMCHG 78
|
|
|
--#define ELIBACC 79
|
|
|
--#define ELIBBAD 80
|
|
|
--#define ELIBSCN 81
|
|
|
--#define ELIBMAX 82
|
|
|
--#define ELIBEXEC 83
|
|
|
--#define EILSEQ 84
|
|
|
--#define ERESTART 85
|
|
|
--#define ESTRPIPE 86
|
|
|
--#define EUSERS 87
|
|
|
--#define ENOTSOCK 88
|
|
|
--#define EDESTADDRREQ 89
|
|
|
--#define EMSGSIZE 90
|
|
|
--#define EPROTOTYPE 91
|
|
|
--#define ENOPROTOOPT 92
|
|
|
--#define EPROTONOSUPPORT 93
|
|
|
--#define ESOCKTNOSUPPORT 94
|
|
|
--#define EOPNOTSUPP 95
|
|
|
--#define ENOTSUP EOPNOTSUPP
|
|
|
--#define EPFNOSUPPORT 96
|
|
|
--#define EAFNOSUPPORT 97
|
|
|
--#define EADDRINUSE 98
|
|
|
--#define EADDRNOTAVAIL 99
|
|
|
--#define ENETDOWN 100
|
|
|
--#define ENETUNREACH 101
|
|
|
--#define ENETRESET 102
|
|
|
--#define ECONNABORTED 103
|
|
|
--#define ECONNRESET 104
|
|
|
--#define ENOBUFS 105
|
|
|
--#define EISCONN 106
|
|
|
--#define ENOTCONN 107
|
|
|
--#define ESHUTDOWN 108
|
|
|
--#define ETOOMANYREFS 109
|
|
|
--#define ETIMEDOUT 110
|
|
|
--#define ECONNREFUSED 111
|
|
|
--#define EHOSTDOWN 112
|
|
|
--#define EHOSTUNREACH 113
|
|
|
--#define EALREADY 114
|
|
|
--#define EINPROGRESS 115
|
|
|
--#define ESTALE 116
|
|
|
--#define EUCLEAN 117
|
|
|
--#define ENOTNAM 118
|
|
|
--#define ENAVAIL 119
|
|
|
--#define EISNAM 120
|
|
|
--#define EREMOTEIO 121
|
|
|
--#define EDQUOT 122
|
|
|
--#define ENOMEDIUM 123
|
|
|
--#define EMEDIUMTYPE 124
|
|
|
--#define ECANCELED 125
|
|
|
--#define ENOKEY 126
|
|
|
--#define EKEYEXPIRED 127
|
|
|
--#define EKEYREVOKED 128
|
|
|
--#define EKEYREJECTED 129
|
|
|
--#define EOWNERDEAD 130
|
|
|
--#define ENOTRECOVERABLE 131
|
|
|
--#define ERFKILL 132
|
|
|
--#define EHWPOISON 133
|
|
|
---- a/arch/microblaze/bits/fcntl.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,40 +0,0 @@
|
|
|
--#define O_CREAT 0100
|
|
|
--#define O_EXCL 0200
|
|
|
--#define O_NOCTTY 0400
|
|
|
--#define O_TRUNC 01000
|
|
|
--#define O_APPEND 02000
|
|
|
--#define O_NONBLOCK 04000
|
|
|
--#define O_DSYNC 010000
|
|
|
--#define O_SYNC 04010000
|
|
|
--#define O_RSYNC 04010000
|
|
|
--#define O_DIRECTORY 0200000
|
|
|
--#define O_NOFOLLOW 0400000
|
|
|
--#define O_CLOEXEC 02000000
|
|
|
--
|
|
|
--#define O_ASYNC 020000
|
|
|
--#define O_DIRECT 040000
|
|
|
--#define O_LARGEFILE 0100000
|
|
|
--#define O_NOATIME 01000000
|
|
|
--#define O_PATH 010000000
|
|
|
--#define O_TMPFILE 020200000
|
|
|
--#define O_NDELAY O_NONBLOCK
|
|
|
--
|
|
|
--#define F_DUPFD 0
|
|
|
--#define F_GETFD 1
|
|
|
--#define F_SETFD 2
|
|
|
--#define F_GETFL 3
|
|
|
--#define F_SETFL 4
|
|
|
--
|
|
|
--#define F_SETOWN 8
|
|
|
--#define F_GETOWN 9
|
|
|
--#define F_SETSIG 10
|
|
|
--#define F_GETSIG 11
|
|
|
--
|
|
|
--#define F_GETLK 12
|
|
|
--#define F_SETLK 13
|
|
|
--#define F_SETLKW 14
|
|
|
--
|
|
|
--#define F_SETOWN_EX 15
|
|
|
--#define F_GETOWN_EX 16
|
|
|
--
|
|
|
--#define F_GETOWNER_UIDS 17
|
|
|
---- a/arch/microblaze/bits/fenv.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,10 +0,0 @@
|
|
|
--#define FE_ALL_EXCEPT 0
|
|
|
--#define FE_TONEAREST 0
|
|
|
--
|
|
|
--typedef unsigned long fexcept_t;
|
|
|
--
|
|
|
--typedef struct {
|
|
|
-- unsigned long __cw;
|
|
|
--} fenv_t;
|
|
|
--
|
|
|
--#define FE_DFL_ENV ((const fenv_t *) -1)
|
|
|
---- a/arch/microblaze/bits/ioctl.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,197 +0,0 @@
|
|
|
--#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
|
|
|
--#define _IOC_NONE 0U
|
|
|
--#define _IOC_WRITE 1U
|
|
|
--#define _IOC_READ 2U
|
|
|
--
|
|
|
--#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
|
|
|
--#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
|
|
|
--#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
|
|
|
--#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
|
|
|
--
|
|
|
--#define TCGETS 0x5401
|
|
|
--#define TCSETS 0x5402
|
|
|
--#define TCSETSW 0x5403
|
|
|
--#define TCSETSF 0x5404
|
|
|
--#define TCGETA 0x5405
|
|
|
--#define TCSETA 0x5406
|
|
|
--#define TCSETAW 0x5407
|
|
|
--#define TCSETAF 0x5408
|
|
|
--#define TCSBRK 0x5409
|
|
|
--#define TCXONC 0x540A
|
|
|
--#define TCFLSH 0x540B
|
|
|
--#define TIOCEXCL 0x540C
|
|
|
--#define TIOCNXCL 0x540D
|
|
|
--#define TIOCSCTTY 0x540E
|
|
|
--#define TIOCGPGRP 0x540F
|
|
|
--#define TIOCSPGRP 0x5410
|
|
|
--#define TIOCOUTQ 0x5411
|
|
|
--#define TIOCSTI 0x5412
|
|
|
--#define TIOCGWINSZ 0x5413
|
|
|
--#define TIOCSWINSZ 0x5414
|
|
|
--#define TIOCMGET 0x5415
|
|
|
--#define TIOCMBIS 0x5416
|
|
|
--#define TIOCMBIC 0x5417
|
|
|
--#define TIOCMSET 0x5418
|
|
|
--#define TIOCGSOFTCAR 0x5419
|
|
|
--#define TIOCSSOFTCAR 0x541A
|
|
|
--#define FIONREAD 0x541B
|
|
|
--#define TIOCINQ FIONREAD
|
|
|
--#define TIOCLINUX 0x541C
|
|
|
--#define TIOCCONS 0x541D
|
|
|
--#define TIOCGSERIAL 0x541E
|
|
|
--#define TIOCSSERIAL 0x541F
|
|
|
--#define TIOCPKT 0x5420
|
|
|
--#define FIONBIO 0x5421
|
|
|
--#define TIOCNOTTY 0x5422
|
|
|
--#define TIOCSETD 0x5423
|
|
|
--#define TIOCGETD 0x5424
|
|
|
--#define TCSBRKP 0x5425
|
|
|
--#define TIOCTTYGSTRUCT 0x5426
|
|
|
--#define TIOCSBRK 0x5427
|
|
|
--#define TIOCCBRK 0x5428
|
|
|
--#define TIOCGSID 0x5429
|
|
|
--#define TIOCGPTN 0x80045430
|
|
|
--#define TIOCSPTLCK 0x40045431
|
|
|
--#define TCGETX 0x5432
|
|
|
--#define TCSETX 0x5433
|
|
|
--#define TCSETXF 0x5434
|
|
|
--#define TCSETXW 0x5435
|
|
|
--
|
|
|
--#define FIONCLEX 0x5450
|
|
|
--#define FIOCLEX 0x5451
|
|
|
--#define FIOASYNC 0x5452
|
|
|
--#define TIOCSERCONFIG 0x5453
|
|
|
--#define TIOCSERGWILD 0x5454
|
|
|
--#define TIOCSERSWILD 0x5455
|
|
|
--#define TIOCGLCKTRMIOS 0x5456
|
|
|
--#define TIOCSLCKTRMIOS 0x5457
|
|
|
--#define TIOCSERGSTRUCT 0x5458
|
|
|
--#define TIOCSERGETLSR 0x5459
|
|
|
--#define TIOCSERGETMULTI 0x545A
|
|
|
--#define TIOCSERSETMULTI 0x545B
|
|
|
--
|
|
|
--#define TIOCMIWAIT 0x545C
|
|
|
--#define TIOCGICOUNT 0x545D
|
|
|
--#define TIOCGHAYESESP 0x545E
|
|
|
--#define TIOCSHAYESESP 0x545F
|
|
|
--#define FIOQSIZE 0x5460
|
|
|
--
|
|
|
--#define TIOCPKT_DATA 0
|
|
|
--#define TIOCPKT_FLUSHREAD 1
|
|
|
--#define TIOCPKT_FLUSHWRITE 2
|
|
|
--#define TIOCPKT_STOP 4
|
|
|
--#define TIOCPKT_START 8
|
|
|
--#define TIOCPKT_NOSTOP 16
|
|
|
--#define TIOCPKT_DOSTOP 32
|
|
|
--#define TIOCPKT_IOCTL 64
|
|
|
--
|
|
|
--#define TIOCSER_TEMT 0x01
|
|
|
--
|
|
|
--struct winsize {
|
|
|
-- unsigned short ws_row;
|
|
|
-- unsigned short ws_col;
|
|
|
-- unsigned short ws_xpixel;
|
|
|
-- unsigned short ws_ypixel;
|
|
|
--};
|
|
|
--
|
|
|
--#define TIOCM_LE 0x001
|
|
|
--#define TIOCM_DTR 0x002
|
|
|
--#define TIOCM_RTS 0x004
|
|
|
--#define TIOCM_ST 0x008
|
|
|
--#define TIOCM_SR 0x010
|
|
|
--#define TIOCM_CTS 0x020
|
|
|
--#define TIOCM_CAR 0x040
|
|
|
--#define TIOCM_RNG 0x080
|
|
|
--#define TIOCM_DSR 0x100
|
|
|
--#define TIOCM_CD TIOCM_CAR
|
|
|
--#define TIOCM_RI TIOCM_RNG
|
|
|
--#define TIOCM_OUT1 0x2000
|
|
|
--#define TIOCM_OUT2 0x4000
|
|
|
--#define TIOCM_LOOP 0x8000
|
|
|
--#define TIOCM_MODEM_BITS TIOCM_OUT2
|
|
|
--
|
|
|
--#define N_TTY 0
|
|
|
--#define N_SLIP 1
|
|
|
--#define N_MOUSE 2
|
|
|
--#define N_PPP 3
|
|
|
--#define N_STRIP 4
|
|
|
--#define N_AX25 5
|
|
|
--#define N_X25 6
|
|
|
--#define N_6PACK 7
|
|
|
--#define N_MASC 8
|
|
|
--#define N_R3964 9
|
|
|
--#define N_PROFIBUS_FDL 10
|
|
|
--#define N_IRDA 11
|
|
|
--#define N_SMSBLOCK 12
|
|
|
--#define N_HDLC 13
|
|
|
--#define N_SYNC_PPP 14
|
|
|
--#define N_HCI 15
|
|
|
--
|
|
|
--#define FIOSETOWN 0x8901
|
|
|
--#define SIOCSPGRP 0x8902
|
|
|
--#define FIOGETOWN 0x8903
|
|
|
--#define SIOCGPGRP 0x8904
|
|
|
--#define SIOCATMARK 0x8905
|
|
|
--#define SIOCGSTAMP 0x8906
|
|
|
--
|
|
|
--#define SIOCADDRT 0x890B
|
|
|
--#define SIOCDELRT 0x890C
|
|
|
--#define SIOCRTMSG 0x890D
|
|
|
--
|
|
|
--#define SIOCGIFNAME 0x8910
|
|
|
--#define SIOCSIFLINK 0x8911
|
|
|
--#define SIOCGIFCONF 0x8912
|
|
|
--#define SIOCGIFFLAGS 0x8913
|
|
|
--#define SIOCSIFFLAGS 0x8914
|
|
|
--#define SIOCGIFADDR 0x8915
|
|
|
--#define SIOCSIFADDR 0x8916
|
|
|
--#define SIOCGIFDSTADDR 0x8917
|
|
|
--#define SIOCSIFDSTADDR 0x8918
|
|
|
--#define SIOCGIFBRDADDR 0x8919
|
|
|
--#define SIOCSIFBRDADDR 0x891a
|
|
|
--#define SIOCGIFNETMASK 0x891b
|
|
|
--#define SIOCSIFNETMASK 0x891c
|
|
|
--#define SIOCGIFMETRIC 0x891d
|
|
|
--#define SIOCSIFMETRIC 0x891e
|
|
|
--#define SIOCGIFMEM 0x891f
|
|
|
--#define SIOCSIFMEM 0x8920
|
|
|
--#define SIOCGIFMTU 0x8921
|
|
|
--#define SIOCSIFMTU 0x8922
|
|
|
--#define SIOCSIFHWADDR 0x8924
|
|
|
--#define SIOCGIFENCAP 0x8925
|
|
|
--#define SIOCSIFENCAP 0x8926
|
|
|
--#define SIOCGIFHWADDR 0x8927
|
|
|
--#define SIOCGIFSLAVE 0x8929
|
|
|
--#define SIOCSIFSLAVE 0x8930
|
|
|
--#define SIOCADDMULTI 0x8931
|
|
|
--#define SIOCDELMULTI 0x8932
|
|
|
--#define SIOCGIFINDEX 0x8933
|
|
|
--#define SIOGIFINDEX SIOCGIFINDEX
|
|
|
--#define SIOCSIFPFLAGS 0x8934
|
|
|
--#define SIOCGIFPFLAGS 0x8935
|
|
|
--#define SIOCDIFADDR 0x8936
|
|
|
--#define SIOCSIFHWBROADCAST 0x8937
|
|
|
--#define SIOCGIFCOUNT 0x8938
|
|
|
--
|
|
|
--#define SIOCGIFBR 0x8940
|
|
|
--#define SIOCSIFBR 0x8941
|
|
|
--
|
|
|
--#define SIOCGIFTXQLEN 0x8942
|
|
|
--#define SIOCSIFTXQLEN 0x8943
|
|
|
--
|
|
|
--#define SIOCDARP 0x8953
|
|
|
--#define SIOCGARP 0x8954
|
|
|
--#define SIOCSARP 0x8955
|
|
|
--
|
|
|
--#define SIOCDRARP 0x8960
|
|
|
--#define SIOCGRARP 0x8961
|
|
|
--#define SIOCSRARP 0x8962
|
|
|
--
|
|
|
--#define SIOCGIFMAP 0x8970
|
|
|
--#define SIOCSIFMAP 0x8971
|
|
|
--
|
|
|
--#define SIOCADDDLCI 0x8980
|
|
|
--#define SIOCDELDLCI 0x8981
|
|
|
--
|
|
|
--#define SIOCDEVPRIVATE 0x89F0
|
|
|
--#define SIOCPROTOPRIVATE 0x89E0
|
|
|
---- a/arch/microblaze/bits/ipc.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,14 +0,0 @@
|
|
|
--struct ipc_perm
|
|
|
--{
|
|
|
-- key_t __ipc_perm_key;
|
|
|
-- uid_t uid;
|
|
|
-- gid_t gid;
|
|
|
-- uid_t cuid;
|
|
|
-- gid_t cgid;
|
|
|
-- mode_t mode;
|
|
|
-- int __ipc_perm_seq;
|
|
|
-- long __pad1;
|
|
|
-- long __pad2;
|
|
|
--};
|
|
|
--
|
|
|
--#define IPC_64 0x100
|
|
|
---- a/arch/microblaze/bits/mman.h
|
|
|
-+++ b/arch/microblaze/bits/mman.h
|
|
|
-@@ -37,6 +37,7 @@
|
|
|
-
|
|
|
- #define MCL_CURRENT 1
|
|
|
- #define MCL_FUTURE 2
|
|
|
-+#define MCL_ONFAULT 4
|
|
|
-
|
|
|
- #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
- #define MADV_NORMAL 0
|
|
|
---- a/arch/microblaze/bits/msg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,16 +0,0 @@
|
|
|
--struct msqid_ds
|
|
|
--{
|
|
|
-- struct ipc_perm msg_perm;
|
|
|
-- time_t msg_stime;
|
|
|
-- int __unused1;
|
|
|
-- time_t msg_rtime;
|
|
|
-- int __unused2;
|
|
|
-- time_t msg_ctime;
|
|
|
-- int __unused3;
|
|
|
-- unsigned long msg_cbytes;
|
|
|
-- msgqnum_t msg_qnum;
|
|
|
-- msglen_t msg_qbytes;
|
|
|
-- pid_t msg_lspid;
|
|
|
-- pid_t msg_lrpid;
|
|
|
-- unsigned long __unused[2];
|
|
|
--};
|
|
|
---- a/arch/microblaze/bits/sem.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,16 +0,0 @@
|
|
|
--struct semid_ds {
|
|
|
-- struct ipc_perm sem_perm;
|
|
|
-- time_t sem_otime;
|
|
|
-- time_t __unused1;
|
|
|
-- time_t sem_ctime;
|
|
|
-- time_t __unused2;
|
|
|
--#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
-- unsigned short sem_nsems;
|
|
|
-- char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
--#else
|
|
|
-- char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
-- unsigned short sem_nsems;
|
|
|
--#endif
|
|
|
-- time_t __unused3;
|
|
|
-- time_t __unused4;
|
|
|
--};
|
|
|
---- a/arch/microblaze/bits/shm.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,29 +0,0 @@
|
|
|
--#define SHMLBA 4096
|
|
|
--
|
|
|
--struct shmid_ds
|
|
|
--{
|
|
|
-- struct ipc_perm shm_perm;
|
|
|
-- size_t shm_segsz;
|
|
|
-- time_t shm_atime;
|
|
|
-- int __unused1;
|
|
|
-- time_t shm_dtime;
|
|
|
-- int __unused2;
|
|
|
-- time_t shm_ctime;
|
|
|
-- int __unused3;
|
|
|
-- pid_t shm_cpid;
|
|
|
-- pid_t shm_lpid;
|
|
|
-- unsigned long shm_nattch;
|
|
|
-- unsigned long __pad1;
|
|
|
-- unsigned long __pad2;
|
|
|
--};
|
|
|
--
|
|
|
--struct shminfo {
|
|
|
-- unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
|
|
|
--};
|
|
|
--
|
|
|
--struct shm_info {
|
|
|
-- int __used_ids;
|
|
|
-- unsigned long shm_tot, shm_rss, shm_swp;
|
|
|
-- unsigned long __swap_attempts, __swap_successes;
|
|
|
--};
|
|
|
--
|
|
|
---- a/arch/microblaze/bits/socket.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,17 +0,0 @@
|
|
|
--struct msghdr
|
|
|
--{
|
|
|
-- void *msg_name;
|
|
|
-- socklen_t msg_namelen;
|
|
|
-- struct iovec *msg_iov;
|
|
|
-- int msg_iovlen;
|
|
|
-- void *msg_control;
|
|
|
-- socklen_t msg_controllen;
|
|
|
-- int msg_flags;
|
|
|
--};
|
|
|
--
|
|
|
--struct cmsghdr
|
|
|
--{
|
|
|
-- socklen_t cmsg_len;
|
|
|
-- int cmsg_level;
|
|
|
-- int cmsg_type;
|
|
|
--};
|
|
|
---- a/arch/microblaze/bits/statfs.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,7 +0,0 @@
|
|
|
--struct statfs {
|
|
|
-- unsigned long f_type, f_bsize;
|
|
|
-- fsblkcnt_t f_blocks, f_bfree, f_bavail;
|
|
|
-- fsfilcnt_t f_files, f_ffree;
|
|
|
-- fsid_t f_fsid;
|
|
|
-- unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
|
|
|
--};
|
|
|
---- a/arch/microblaze/bits/stdarg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,4 +0,0 @@
|
|
|
--#define va_start(v,l) __builtin_va_start(v,l)
|
|
|
--#define va_end(v) __builtin_va_end(v)
|
|
|
--#define va_arg(v,l) __builtin_va_arg(v,l)
|
|
|
--#define va_copy(d,s) __builtin_va_copy(d,s)
|
|
|
---- a/arch/microblaze/bits/termios.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,160 +0,0 @@
|
|
|
--struct termios
|
|
|
--{
|
|
|
-- tcflag_t c_iflag;
|
|
|
-- tcflag_t c_oflag;
|
|
|
-- tcflag_t c_cflag;
|
|
|
-- tcflag_t c_lflag;
|
|
|
-- cc_t c_line;
|
|
|
-- cc_t c_cc[NCCS];
|
|
|
-- speed_t __c_ispeed;
|
|
|
-- speed_t __c_ospeed;
|
|
|
--};
|
|
|
--
|
|
|
--#define VINTR 0
|
|
|
--#define VQUIT 1
|
|
|
--#define VERASE 2
|
|
|
--#define VKILL 3
|
|
|
--#define VEOF 4
|
|
|
--#define VTIME 5
|
|
|
--#define VMIN 6
|
|
|
--#define VSWTC 7
|
|
|
--#define VSTART 8
|
|
|
--#define VSTOP 9
|
|
|
--#define VSUSP 10
|
|
|
--#define VEOL 11
|
|
|
--#define VREPRINT 12
|
|
|
--#define VDISCARD 13
|
|
|
--#define VWERASE 14
|
|
|
--#define VLNEXT 15
|
|
|
--#define VEOL2 16
|
|
|
--
|
|
|
--#define IGNBRK 0000001
|
|
|
--#define BRKINT 0000002
|
|
|
--#define IGNPAR 0000004
|
|
|
--#define PARMRK 0000010
|
|
|
--#define INPCK 0000020
|
|
|
--#define ISTRIP 0000040
|
|
|
--#define INLCR 0000100
|
|
|
--#define IGNCR 0000200
|
|
|
--#define ICRNL 0000400
|
|
|
--#define IUCLC 0001000
|
|
|
--#define IXON 0002000
|
|
|
--#define IXANY 0004000
|
|
|
--#define IXOFF 0010000
|
|
|
--#define IMAXBEL 0020000
|
|
|
--#define IUTF8 0040000
|
|
|
--
|
|
|
--#define OPOST 0000001
|
|
|
--#define OLCUC 0000002
|
|
|
--#define ONLCR 0000004
|
|
|
--#define OCRNL 0000010
|
|
|
--#define ONOCR 0000020
|
|
|
--#define ONLRET 0000040
|
|
|
--#define OFILL 0000100
|
|
|
--#define OFDEL 0000200
|
|
|
--#define NLDLY 0000400
|
|
|
--#define NL0 0000000
|
|
|
--#define NL1 0000400
|
|
|
--#define CRDLY 0003000
|
|
|
--#define CR0 0000000
|
|
|
--#define CR1 0001000
|
|
|
--#define CR2 0002000
|
|
|
--#define CR3 0003000
|
|
|
--#define TABDLY 0014000
|
|
|
--#define TAB0 0000000
|
|
|
--#define TAB1 0004000
|
|
|
--#define TAB2 0010000
|
|
|
--#define TAB3 0014000
|
|
|
--#define BSDLY 0020000
|
|
|
--#define BS0 0000000
|
|
|
--#define BS1 0020000
|
|
|
--#define FFDLY 0100000
|
|
|
--#define FF0 0000000
|
|
|
--#define FF1 0100000
|
|
|
--
|
|
|
--#define VTDLY 0040000
|
|
|
--#define VT0 0000000
|
|
|
--#define VT1 0040000
|
|
|
--
|
|
|
--#define B0 0000000
|
|
|
--#define B50 0000001
|
|
|
--#define B75 0000002
|
|
|
--#define B110 0000003
|
|
|
--#define B134 0000004
|
|
|
--#define B150 0000005
|
|
|
--#define B200 0000006
|
|
|
--#define B300 0000007
|
|
|
--#define B600 0000010
|
|
|
--#define B1200 0000011
|
|
|
--#define B1800 0000012
|
|
|
--#define B2400 0000013
|
|
|
--#define B4800 0000014
|
|
|
--#define B9600 0000015
|
|
|
--#define B19200 0000016
|
|
|
--#define B38400 0000017
|
|
|
--
|
|
|
--#define B57600 0010001
|
|
|
--#define B115200 0010002
|
|
|
--#define B230400 0010003
|
|
|
--#define B460800 0010004
|
|
|
--#define B500000 0010005
|
|
|
--#define B576000 0010006
|
|
|
--#define B921600 0010007
|
|
|
--#define B1000000 0010010
|
|
|
--#define B1152000 0010011
|
|
|
--#define B1500000 0010012
|
|
|
--#define B2000000 0010013
|
|
|
--#define B2500000 0010014
|
|
|
--#define B3000000 0010015
|
|
|
--#define B3500000 0010016
|
|
|
--#define B4000000 0010017
|
|
|
--
|
|
|
--#define CBAUD 0010017
|
|
|
--
|
|
|
--#define CSIZE 0000060
|
|
|
--#define CS5 0000000
|
|
|
--#define CS6 0000020
|
|
|
--#define CS7 0000040
|
|
|
--#define CS8 0000060
|
|
|
--#define CSTOPB 0000100
|
|
|
--#define CREAD 0000200
|
|
|
--#define PARENB 0000400
|
|
|
--#define PARODD 0001000
|
|
|
--#define HUPCL 0002000
|
|
|
--#define CLOCAL 0004000
|
|
|
--
|
|
|
--#define ISIG 0000001
|
|
|
--#define ICANON 0000002
|
|
|
--#define ECHO 0000010
|
|
|
--#define ECHOE 0000020
|
|
|
--#define ECHOK 0000040
|
|
|
--#define ECHONL 0000100
|
|
|
--#define NOFLSH 0000200
|
|
|
--#define TOSTOP 0000400
|
|
|
--#define IEXTEN 0100000
|
|
|
--
|
|
|
--#define ECHOCTL 0001000
|
|
|
--#define ECHOPRT 0002000
|
|
|
--#define ECHOKE 0004000
|
|
|
--#define FLUSHO 0010000
|
|
|
--#define PENDIN 0040000
|
|
|
--
|
|
|
--#define TCOOFF 0
|
|
|
--#define TCOON 1
|
|
|
--#define TCIOFF 2
|
|
|
--#define TCION 3
|
|
|
--
|
|
|
--#define TCIFLUSH 0
|
|
|
--#define TCOFLUSH 1
|
|
|
--#define TCIOFLUSH 2
|
|
|
--
|
|
|
--#define TCSANOW 0
|
|
|
--#define TCSADRAIN 1
|
|
|
--#define TCSAFLUSH 2
|
|
|
--
|
|
|
--#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
--#define CBAUDEX 0010000
|
|
|
--#define CRTSCTS 020000000000
|
|
|
--#define EXTPROC 0200000
|
|
|
--#define XTABS 0014000
|
|
|
--#endif
|
|
|
---- a/arch/microblaze/pthread_arch.h
|
|
|
-+++ b/arch/microblaze/pthread_arch.h
|
|
|
-@@ -7,4 +7,4 @@ static inline struct pthread *__pthread_
|
|
|
-
|
|
|
- #define TP_ADJ(p) (p)
|
|
|
-
|
|
|
--#define CANCEL_REG_IP 32
|
|
|
-+#define MC_PC regs.pc
|
|
|
---- a/arch/mips/atomic.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,205 +0,0 @@
|
|
|
--#ifndef _INTERNAL_ATOMIC_H
|
|
|
--#define _INTERNAL_ATOMIC_H
|
|
|
--
|
|
|
--#include <stdint.h>
|
|
|
--
|
|
|
--static inline int a_ctz_l(unsigned long x)
|
|
|
--{
|
|
|
-- static const char debruijn32[32] = {
|
|
|
-- 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
|
|
|
-- 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
|
|
|
-- };
|
|
|
-- return debruijn32[(x&-x)*0x076be629 >> 27];
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_ctz_64(uint64_t x)
|
|
|
--{
|
|
|
-- uint32_t y = x;
|
|
|
-- if (!y) {
|
|
|
-- y = x>>32;
|
|
|
-- return 32 + a_ctz_l(y);
|
|
|
-- }
|
|
|
-- return a_ctz_l(y);
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_cas(volatile int *p, int t, int s)
|
|
|
--{
|
|
|
-- int dummy;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- ".set push\n"
|
|
|
-- ".set mips2\n"
|
|
|
-- ".set noreorder\n"
|
|
|
-- " sync\n"
|
|
|
-- "1: ll %0, %2\n"
|
|
|
-- " bne %0, %3, 1f\n"
|
|
|
-- " addu %1, %4, $0\n"
|
|
|
-- " sc %1, %2\n"
|
|
|
-- " beq %1, $0, 1b\n"
|
|
|
-- " nop\n"
|
|
|
-- " sync\n"
|
|
|
-- "1: \n"
|
|
|
-- ".set pop\n"
|
|
|
-- : "=&r"(t), "=&r"(dummy), "+m"(*p) : "r"(t), "r"(s) : "memory" );
|
|
|
-- return t;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
--{
|
|
|
-- return (void *)a_cas(p, (int)t, (int)s);
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_swap(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old, dummy;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- ".set push\n"
|
|
|
-- ".set mips2\n"
|
|
|
-- ".set noreorder\n"
|
|
|
-- " sync\n"
|
|
|
-- "1: ll %0, %2\n"
|
|
|
-- " addu %1, %3, $0\n"
|
|
|
-- " sc %1, %2\n"
|
|
|
-- " beq %1, $0, 1b\n"
|
|
|
-- " nop\n"
|
|
|
-- " sync\n"
|
|
|
-- ".set pop\n"
|
|
|
-- : "=&r"(old), "=&r"(dummy), "+m"(*x) : "r"(v) : "memory" );
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_fetch_add(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old, dummy;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- ".set push\n"
|
|
|
-- ".set mips2\n"
|
|
|
-- ".set noreorder\n"
|
|
|
-- " sync\n"
|
|
|
-- "1: ll %0, %2\n"
|
|
|
-- " addu %1, %0, %3\n"
|
|
|
-- " sc %1, %2\n"
|
|
|
-- " beq %1, $0, 1b\n"
|
|
|
-- " nop\n"
|
|
|
-- " sync\n"
|
|
|
-- ".set pop\n"
|
|
|
-- : "=&r"(old), "=&r"(dummy), "+m"(*x) : "r"(v) : "memory" );
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_inc(volatile int *x)
|
|
|
--{
|
|
|
-- int dummy;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- ".set push\n"
|
|
|
-- ".set mips2\n"
|
|
|
-- ".set noreorder\n"
|
|
|
-- " sync\n"
|
|
|
-- "1: ll %0, %1\n"
|
|
|
-- " addu %0, %0, 1\n"
|
|
|
-- " sc %0, %1\n"
|
|
|
-- " beq %0, $0, 1b\n"
|
|
|
-- " nop\n"
|
|
|
-- " sync\n"
|
|
|
-- ".set pop\n"
|
|
|
-- : "=&r"(dummy), "+m"(*x) : : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_dec(volatile int *x)
|
|
|
--{
|
|
|
-- int dummy;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- ".set push\n"
|
|
|
-- ".set mips2\n"
|
|
|
-- ".set noreorder\n"
|
|
|
-- " sync\n"
|
|
|
-- "1: ll %0, %1\n"
|
|
|
-- " subu %0, %0, 1\n"
|
|
|
-- " sc %0, %1\n"
|
|
|
-- " beq %0, $0, 1b\n"
|
|
|
-- " nop\n"
|
|
|
-- " sync\n"
|
|
|
-- ".set pop\n"
|
|
|
-- : "=&r"(dummy), "+m"(*x) : : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_store(volatile int *p, int x)
|
|
|
--{
|
|
|
-- __asm__ __volatile__(
|
|
|
-- ".set push\n"
|
|
|
-- ".set mips2\n"
|
|
|
-- ".set noreorder\n"
|
|
|
-- " sync\n"
|
|
|
-- " sw %1, %0\n"
|
|
|
-- " sync\n"
|
|
|
-- ".set pop\n"
|
|
|
-- : "+m"(*p) : "r"(x) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--#define a_spin a_barrier
|
|
|
--
|
|
|
--static inline void a_barrier()
|
|
|
--{
|
|
|
-- a_cas(&(int){0}, 0, 0);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_crash()
|
|
|
--{
|
|
|
-- *(volatile char *)0=0;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and(volatile int *p, int v)
|
|
|
--{
|
|
|
-- int dummy;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- ".set push\n"
|
|
|
-- ".set mips2\n"
|
|
|
-- ".set noreorder\n"
|
|
|
-- " sync\n"
|
|
|
-- "1: ll %0, %1\n"
|
|
|
-- " and %0, %0, %2\n"
|
|
|
-- " sc %0, %1\n"
|
|
|
-- " beq %0, $0, 1b\n"
|
|
|
-- " nop\n"
|
|
|
-- " sync\n"
|
|
|
-- ".set pop\n"
|
|
|
-- : "=&r"(dummy), "+m"(*p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or(volatile int *p, int v)
|
|
|
--{
|
|
|
-- int dummy;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- ".set push\n"
|
|
|
-- ".set mips2\n"
|
|
|
-- ".set noreorder\n"
|
|
|
-- " sync\n"
|
|
|
-- "1: ll %0, %1\n"
|
|
|
-- " or %0, %0, %2\n"
|
|
|
-- " sc %0, %1\n"
|
|
|
-- " beq %0, $0, 1b\n"
|
|
|
-- " nop\n"
|
|
|
-- " sync\n"
|
|
|
-- ".set pop\n"
|
|
|
-- : "=&r"(dummy), "+m"(*p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_l(volatile void *p, long v)
|
|
|
--{
|
|
|
-- a_or(p, v);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-- a_and((int *)p, u.r[0]);
|
|
|
-- a_and((int *)p+1, u.r[1]);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-- a_or((int *)p, u.r[0]);
|
|
|
-- a_or((int *)p+1, u.r[1]);
|
|
|
--}
|
|
|
--
|
|
|
--#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/mips/atomic_arch.h
|
|
|
-@@ -0,0 +1,39 @@
|
|
|
-+#define a_ll a_ll
|
|
|
-+static inline int a_ll(volatile int *p)
|
|
|
-+{
|
|
|
-+ int v;
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ ".set push ; .set mips2\n\t"
|
|
|
-+ "ll %0, %1"
|
|
|
-+ "\n\t.set pop"
|
|
|
-+ : "=r"(v) : "m"(*p));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_sc a_sc
|
|
|
-+static inline int a_sc(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int r;
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ ".set push ; .set mips2\n\t"
|
|
|
-+ "sc %0, %1"
|
|
|
-+ "\n\t.set pop"
|
|
|
-+ : "=r"(r), "=m"(*p) : "0"(v) : "memory");
|
|
|
-+ return r;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_barrier a_barrier
|
|
|
-+static inline void a_barrier()
|
|
|
-+{
|
|
|
-+ /* mips2 sync, but using too many directives causes
|
|
|
-+ * gcc not to inline it, so encode with .long instead. */
|
|
|
-+ __asm__ __volatile__ (".long 0xf" : : : "memory");
|
|
|
-+#if 0
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ ".set push ; .set mips2 ; sync ; .set pop"
|
|
|
-+ : : : "memory");
|
|
|
-+#endif
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_pre_llsc a_barrier
|
|
|
-+#define a_post_llsc a_barrier
|
|
|
---- a/arch/mips/bits/ipc.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,14 +0,0 @@
|
|
|
--struct ipc_perm
|
|
|
--{
|
|
|
-- key_t __ipc_perm_key;
|
|
|
-- uid_t uid;
|
|
|
-- gid_t gid;
|
|
|
-- uid_t cuid;
|
|
|
-- gid_t cgid;
|
|
|
-- mode_t mode;
|
|
|
-- int __ipc_perm_seq;
|
|
|
-- long __pad1;
|
|
|
-- long __pad2;
|
|
|
--};
|
|
|
--
|
|
|
--#define IPC_64 0x100
|
|
|
---- a/arch/mips/bits/mman.h
|
|
|
-+++ b/arch/mips/bits/mman.h
|
|
|
-@@ -37,6 +37,7 @@
|
|
|
-
|
|
|
- #define MCL_CURRENT 1
|
|
|
- #define MCL_FUTURE 2
|
|
|
-+#define MCL_ONFAULT 4
|
|
|
-
|
|
|
- #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
- #define MADV_NORMAL 0
|
|
|
---- a/arch/mips/bits/signal.h
|
|
|
-+++ b/arch/mips/bits/signal.h
|
|
|
-@@ -73,6 +73,15 @@ typedef struct __ucontext {
|
|
|
- #define SIG_UNBLOCK 2
|
|
|
- #define SIG_SETMASK 3
|
|
|
-
|
|
|
-+#undef SI_ASYNCIO
|
|
|
-+#undef SI_MESGQ
|
|
|
-+#undef SI_TIMER
|
|
|
-+#define SI_ASYNCIO (-2)
|
|
|
-+#define SI_MESGQ (-4)
|
|
|
-+#define SI_TIMER (-3)
|
|
|
-+
|
|
|
-+#define __SI_SWAP_ERRNO_CODE
|
|
|
-+
|
|
|
- #endif
|
|
|
-
|
|
|
- #define SIGHUP 1
|
|
|
---- a/arch/mips/bits/stdarg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,4 +0,0 @@
|
|
|
--#define va_start(v,l) __builtin_va_start(v,l)
|
|
|
--#define va_end(v) __builtin_va_end(v)
|
|
|
--#define va_arg(v,l) __builtin_va_arg(v,l)
|
|
|
--#define va_copy(d,s) __builtin_va_copy(d,s)
|
|
|
---- a/arch/mips/bits/syscall.h
|
|
|
-+++ b/arch/mips/bits/syscall.h
|
|
|
-@@ -354,6 +354,9 @@
|
|
|
- #define __NR_memfd_create 4354
|
|
|
- #define __NR_bpf 4355
|
|
|
- #define __NR_execveat 4356
|
|
|
-+#define __NR_userfaultfd 4357
|
|
|
-+#define __NR_membarrier 4358
|
|
|
-+#define __NR_mlock2 4359
|
|
|
-
|
|
|
-
|
|
|
- /* Repeated with SYS_ prefix */
|
|
|
-@@ -713,3 +716,6 @@
|
|
|
- #define SYS_memfd_create 4354
|
|
|
- #define SYS_bpf 4355
|
|
|
- #define SYS_execveat 4356
|
|
|
-+#define SYS_userfaultfd 4357
|
|
|
-+#define SYS_membarrier 4358
|
|
|
-+#define SYS_mlock2 4359
|
|
|
---- a/arch/mips/crt_arch.h
|
|
|
-+++ b/arch/mips/crt_arch.h
|
|
|
-@@ -4,13 +4,16 @@ __asm__(
|
|
|
- ".text \n"
|
|
|
- ".global _" START "\n"
|
|
|
- ".global " START "\n"
|
|
|
-+".global " START "_data\n"
|
|
|
- ".type _" START ", @function\n"
|
|
|
- ".type " START ", @function\n"
|
|
|
-+".type " START "_data, @function\n"
|
|
|
- "_" START ":\n"
|
|
|
- "" START ":\n"
|
|
|
- " bal 1f \n"
|
|
|
- " move $fp, $0 \n"
|
|
|
--"2: .gpword 2b \n"
|
|
|
-+"" START "_data: \n"
|
|
|
-+" .gpword " START "_data \n"
|
|
|
- " .gpword " START "_c \n"
|
|
|
- ".weak _DYNAMIC \n"
|
|
|
- ".hidden _DYNAMIC \n"
|
|
|
---- a/arch/mips/pthread_arch.h
|
|
|
-+++ b/arch/mips/pthread_arch.h
|
|
|
-@@ -16,4 +16,4 @@ static inline struct pthread *__pthread_
|
|
|
-
|
|
|
- #define DTP_OFFSET 0x8000
|
|
|
-
|
|
|
--#define CANCEL_REG_IP (3-(union {int __i; char __b;}){1}.__b)
|
|
|
-+#define MC_PC pc
|
|
|
---- a/arch/mips/syscall_arch.h
|
|
|
-+++ b/arch/mips/syscall_arch.h
|
|
|
-@@ -3,9 +3,7 @@
|
|
|
- ((union { long long ll; long l[2]; }){ .ll = x }).l[1]
|
|
|
- #define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
|
|
|
-
|
|
|
--#ifdef SHARED
|
|
|
- __attribute__((visibility("hidden")))
|
|
|
--#endif
|
|
|
- long (__syscall)(long, ...);
|
|
|
-
|
|
|
- #define SYSCALL_RLIM_INFINITY (-1UL/2)
|
|
|
-@@ -163,3 +161,7 @@ static inline long __syscall6(long n, lo
|
|
|
- if (n == SYS_fstatat) __stat_fix(c);
|
|
|
- return r2;
|
|
|
- }
|
|
|
-+
|
|
|
-+#define VDSO_USEFUL
|
|
|
-+#define VDSO_CGT_SYM "__vdso_clock_gettime"
|
|
|
-+#define VDSO_CGT_VER "LINUX_2.6"
|
|
|
---- a/arch/or1k/atomic.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,120 +0,0 @@
|
|
|
--#ifndef _INTERNAL_ATOMIC_H
|
|
|
--#define _INTERNAL_ATOMIC_H
|
|
|
--
|
|
|
--#include <stdint.h>
|
|
|
--
|
|
|
--static inline int a_ctz_l(unsigned long x)
|
|
|
--{
|
|
|
-- static const char debruijn32[32] = {
|
|
|
-- 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
|
|
|
-- 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
|
|
|
-- };
|
|
|
-- return debruijn32[(x&-x)*0x076be629 >> 27];
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_ctz_64(uint64_t x)
|
|
|
--{
|
|
|
-- uint32_t y = x;
|
|
|
-- if (!y) {
|
|
|
-- y = x>>32;
|
|
|
-- return 32 + a_ctz_l(y);
|
|
|
-- }
|
|
|
-- return a_ctz_l(y);
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_cas(volatile int *p, int t, int s)
|
|
|
--{
|
|
|
-- __asm__("1: l.lwa %0, %1\n"
|
|
|
-- " l.sfeq %0, %2\n"
|
|
|
-- " l.bnf 1f\n"
|
|
|
-- " l.nop\n"
|
|
|
-- " l.swa %1, %3\n"
|
|
|
-- " l.bnf 1b\n"
|
|
|
-- " l.nop\n"
|
|
|
-- "1: \n"
|
|
|
-- : "=&r"(t), "+m"(*p) : "r"(t), "r"(s) : "cc", "memory" );
|
|
|
-- return t;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
--{
|
|
|
-- return (void *)a_cas(p, (int)t, (int)s);
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_swap(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *x;
|
|
|
-- while (a_cas(x, old, v) != old);
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_fetch_add(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *x;
|
|
|
-- while (a_cas(x, old, old+v) != old);
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_inc(volatile int *x)
|
|
|
--{
|
|
|
-- a_fetch_add(x, 1);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_dec(volatile int *x)
|
|
|
--{
|
|
|
-- a_fetch_add(x, -1);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_store(volatile int *p, int x)
|
|
|
--{
|
|
|
-- a_swap(p, x);
|
|
|
--}
|
|
|
--
|
|
|
--#define a_spin a_barrier
|
|
|
--
|
|
|
--static inline void a_barrier()
|
|
|
--{
|
|
|
-- a_cas(&(int){0}, 0, 0);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_crash()
|
|
|
--{
|
|
|
-- *(volatile char *)0=0;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and(volatile int *p, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *p;
|
|
|
-- while (a_cas(p, old, old&v) != old);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or(volatile int *p, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *p;
|
|
|
-- while (a_cas(p, old, old|v) != old);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_l(volatile void *p, long v)
|
|
|
--{
|
|
|
-- a_or(p, v);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-- a_and((int *)p, u.r[0]);
|
|
|
-- a_and((int *)p+1, u.r[1]);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-- a_or((int *)p, u.r[0]);
|
|
|
-- a_or((int *)p+1, u.r[1]);
|
|
|
--}
|
|
|
--
|
|
|
--#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/or1k/atomic_arch.h
|
|
|
-@@ -0,0 +1,14 @@
|
|
|
-+#define a_cas a_cas
|
|
|
-+static inline int a_cas(volatile int *p, int t, int s)
|
|
|
-+{
|
|
|
-+ __asm__("1: l.lwa %0, %1\n"
|
|
|
-+ " l.sfeq %0, %2\n"
|
|
|
-+ " l.bnf 1f\n"
|
|
|
-+ " l.nop\n"
|
|
|
-+ " l.swa %1, %3\n"
|
|
|
-+ " l.bnf 1b\n"
|
|
|
-+ " l.nop\n"
|
|
|
-+ "1: \n"
|
|
|
-+ : "=&r"(t), "+m"(*p) : "r"(t), "r"(s) : "cc", "memory" );
|
|
|
-+ return t;
|
|
|
-+}
|
|
|
---- a/arch/or1k/bits/errno.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,134 +0,0 @@
|
|
|
--#define EPERM 1
|
|
|
--#define ENOENT 2
|
|
|
--#define ESRCH 3
|
|
|
--#define EINTR 4
|
|
|
--#define EIO 5
|
|
|
--#define ENXIO 6
|
|
|
--#define E2BIG 7
|
|
|
--#define ENOEXEC 8
|
|
|
--#define EBADF 9
|
|
|
--#define ECHILD 10
|
|
|
--#define EAGAIN 11
|
|
|
--#define ENOMEM 12
|
|
|
--#define EACCES 13
|
|
|
--#define EFAULT 14
|
|
|
--#define ENOTBLK 15
|
|
|
--#define EBUSY 16
|
|
|
--#define EEXIST 17
|
|
|
--#define EXDEV 18
|
|
|
--#define ENODEV 19
|
|
|
--#define ENOTDIR 20
|
|
|
--#define EISDIR 21
|
|
|
--#define EINVAL 22
|
|
|
--#define ENFILE 23
|
|
|
--#define EMFILE 24
|
|
|
--#define ENOTTY 25
|
|
|
--#define ETXTBSY 26
|
|
|
--#define EFBIG 27
|
|
|
--#define ENOSPC 28
|
|
|
--#define ESPIPE 29
|
|
|
--#define EROFS 30
|
|
|
--#define EMLINK 31
|
|
|
--#define EPIPE 32
|
|
|
--#define EDOM 33
|
|
|
--#define ERANGE 34
|
|
|
--#define EDEADLK 35
|
|
|
--#define ENAMETOOLONG 36
|
|
|
--#define ENOLCK 37
|
|
|
--#define ENOSYS 38
|
|
|
--#define ENOTEMPTY 39
|
|
|
--#define ELOOP 40
|
|
|
--#define EWOULDBLOCK EAGAIN
|
|
|
--#define ENOMSG 42
|
|
|
--#define EIDRM 43
|
|
|
--#define ECHRNG 44
|
|
|
--#define EL2NSYNC 45
|
|
|
--#define EL3HLT 46
|
|
|
--#define EL3RST 47
|
|
|
--#define ELNRNG 48
|
|
|
--#define EUNATCH 49
|
|
|
--#define ENOCSI 50
|
|
|
--#define EL2HLT 51
|
|
|
--#define EBADE 52
|
|
|
--#define EBADR 53
|
|
|
--#define EXFULL 54
|
|
|
--#define ENOANO 55
|
|
|
--#define EBADRQC 56
|
|
|
--#define EBADSLT 57
|
|
|
--#define EDEADLOCK EDEADLK
|
|
|
--#define EBFONT 59
|
|
|
--#define ENOSTR 60
|
|
|
--#define ENODATA 61
|
|
|
--#define ETIME 62
|
|
|
--#define ENOSR 63
|
|
|
--#define ENONET 64
|
|
|
--#define ENOPKG 65
|
|
|
--#define EREMOTE 66
|
|
|
--#define ENOLINK 67
|
|
|
--#define EADV 68
|
|
|
--#define ESRMNT 69
|
|
|
--#define ECOMM 70
|
|
|
--#define EPROTO 71
|
|
|
--#define EMULTIHOP 72
|
|
|
--#define EDOTDOT 73
|
|
|
--#define EBADMSG 74
|
|
|
--#define EOVERFLOW 75
|
|
|
--#define ENOTUNIQ 76
|
|
|
--#define EBADFD 77
|
|
|
--#define EREMCHG 78
|
|
|
--#define ELIBACC 79
|
|
|
--#define ELIBBAD 80
|
|
|
--#define ELIBSCN 81
|
|
|
--#define ELIBMAX 82
|
|
|
--#define ELIBEXEC 83
|
|
|
--#define EILSEQ 84
|
|
|
--#define ERESTART 85
|
|
|
--#define ESTRPIPE 86
|
|
|
--#define EUSERS 87
|
|
|
--#define ENOTSOCK 88
|
|
|
--#define EDESTADDRREQ 89
|
|
|
--#define EMSGSIZE 90
|
|
|
--#define EPROTOTYPE 91
|
|
|
--#define ENOPROTOOPT 92
|
|
|
--#define EPROTONOSUPPORT 93
|
|
|
--#define ESOCKTNOSUPPORT 94
|
|
|
--#define EOPNOTSUPP 95
|
|
|
--#define ENOTSUP EOPNOTSUPP
|
|
|
--#define EPFNOSUPPORT 96
|
|
|
--#define EAFNOSUPPORT 97
|
|
|
--#define EADDRINUSE 98
|
|
|
--#define EADDRNOTAVAIL 99
|
|
|
--#define ENETDOWN 100
|
|
|
--#define ENETUNREACH 101
|
|
|
--#define ENETRESET 102
|
|
|
--#define ECONNABORTED 103
|
|
|
--#define ECONNRESET 104
|
|
|
--#define ENOBUFS 105
|
|
|
--#define EISCONN 106
|
|
|
--#define ENOTCONN 107
|
|
|
--#define ESHUTDOWN 108
|
|
|
--#define ETOOMANYREFS 109
|
|
|
--#define ETIMEDOUT 110
|
|
|
--#define ECONNREFUSED 111
|
|
|
--#define EHOSTDOWN 112
|
|
|
--#define EHOSTUNREACH 113
|
|
|
--#define EALREADY 114
|
|
|
--#define EINPROGRESS 115
|
|
|
--#define ESTALE 116
|
|
|
--#define EUCLEAN 117
|
|
|
--#define ENOTNAM 118
|
|
|
--#define ENAVAIL 119
|
|
|
--#define EISNAM 120
|
|
|
--#define EREMOTEIO 121
|
|
|
--#define EDQUOT 122
|
|
|
--#define ENOMEDIUM 123
|
|
|
--#define EMEDIUMTYPE 124
|
|
|
--#define ECANCELED 125
|
|
|
--#define ENOKEY 126
|
|
|
--#define EKEYEXPIRED 127
|
|
|
--#define EKEYREVOKED 128
|
|
|
--#define EKEYREJECTED 129
|
|
|
--#define EOWNERDEAD 130
|
|
|
--#define ENOTRECOVERABLE 131
|
|
|
--#define ERFKILL 132
|
|
|
--#define EHWPOISON 133
|
|
|
---- a/arch/or1k/bits/fcntl.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,40 +0,0 @@
|
|
|
--#define O_CREAT 0100
|
|
|
--#define O_EXCL 0200
|
|
|
--#define O_NOCTTY 0400
|
|
|
--#define O_TRUNC 01000
|
|
|
--#define O_APPEND 02000
|
|
|
--#define O_NONBLOCK 04000
|
|
|
--#define O_DSYNC 010000
|
|
|
--#define O_SYNC 04010000
|
|
|
--#define O_RSYNC 04010000
|
|
|
--#define O_DIRECTORY 0200000
|
|
|
--#define O_NOFOLLOW 0400000
|
|
|
--#define O_CLOEXEC 02000000
|
|
|
--
|
|
|
--#define O_ASYNC 020000
|
|
|
--#define O_DIRECT 040000
|
|
|
--#define O_LARGEFILE 0100000
|
|
|
--#define O_NOATIME 01000000
|
|
|
--#define O_PATH 010000000
|
|
|
--#define O_TMPFILE 020200000
|
|
|
--#define O_NDELAY O_NONBLOCK
|
|
|
--
|
|
|
--#define F_DUPFD 0
|
|
|
--#define F_GETFD 1
|
|
|
--#define F_SETFD 2
|
|
|
--#define F_GETFL 3
|
|
|
--#define F_SETFL 4
|
|
|
--
|
|
|
--#define F_SETOWN 8
|
|
|
--#define F_GETOWN 9
|
|
|
--#define F_SETSIG 10
|
|
|
--#define F_GETSIG 11
|
|
|
--
|
|
|
--#define F_GETLK 12
|
|
|
--#define F_SETLK 13
|
|
|
--#define F_SETLKW 14
|
|
|
--
|
|
|
--#define F_SETOWN_EX 15
|
|
|
--#define F_GETOWN_EX 16
|
|
|
--
|
|
|
--#define F_GETOWNER_UIDS 17
|
|
|
---- a/arch/or1k/bits/fenv.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,10 +0,0 @@
|
|
|
--#define FE_ALL_EXCEPT 0
|
|
|
--#define FE_TONEAREST 0
|
|
|
--
|
|
|
--typedef unsigned long fexcept_t;
|
|
|
--
|
|
|
--typedef struct {
|
|
|
-- unsigned long __cw;
|
|
|
--} fenv_t;
|
|
|
--
|
|
|
--#define FE_DFL_ENV ((const fenv_t *) -1)
|
|
|
---- a/arch/or1k/bits/ioctl.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,197 +0,0 @@
|
|
|
--#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
|
|
|
--#define _IOC_NONE 0U
|
|
|
--#define _IOC_WRITE 1U
|
|
|
--#define _IOC_READ 2U
|
|
|
--
|
|
|
--#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
|
|
|
--#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
|
|
|
--#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
|
|
|
--#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
|
|
|
--
|
|
|
--#define TCGETS 0x5401
|
|
|
--#define TCSETS 0x5402
|
|
|
--#define TCSETSW 0x5403
|
|
|
--#define TCSETSF 0x5404
|
|
|
--#define TCGETA 0x5405
|
|
|
--#define TCSETA 0x5406
|
|
|
--#define TCSETAW 0x5407
|
|
|
--#define TCSETAF 0x5408
|
|
|
--#define TCSBRK 0x5409
|
|
|
--#define TCXONC 0x540A
|
|
|
--#define TCFLSH 0x540B
|
|
|
--#define TIOCEXCL 0x540C
|
|
|
--#define TIOCNXCL 0x540D
|
|
|
--#define TIOCSCTTY 0x540E
|
|
|
--#define TIOCGPGRP 0x540F
|
|
|
--#define TIOCSPGRP 0x5410
|
|
|
--#define TIOCOUTQ 0x5411
|
|
|
--#define TIOCSTI 0x5412
|
|
|
--#define TIOCGWINSZ 0x5413
|
|
|
--#define TIOCSWINSZ 0x5414
|
|
|
--#define TIOCMGET 0x5415
|
|
|
--#define TIOCMBIS 0x5416
|
|
|
--#define TIOCMBIC 0x5417
|
|
|
--#define TIOCMSET 0x5418
|
|
|
--#define TIOCGSOFTCAR 0x5419
|
|
|
--#define TIOCSSOFTCAR 0x541A
|
|
|
--#define FIONREAD 0x541B
|
|
|
--#define TIOCINQ FIONREAD
|
|
|
--#define TIOCLINUX 0x541C
|
|
|
--#define TIOCCONS 0x541D
|
|
|
--#define TIOCGSERIAL 0x541E
|
|
|
--#define TIOCSSERIAL 0x541F
|
|
|
--#define TIOCPKT 0x5420
|
|
|
--#define FIONBIO 0x5421
|
|
|
--#define TIOCNOTTY 0x5422
|
|
|
--#define TIOCSETD 0x5423
|
|
|
--#define TIOCGETD 0x5424
|
|
|
--#define TCSBRKP 0x5425
|
|
|
--#define TIOCTTYGSTRUCT 0x5426
|
|
|
--#define TIOCSBRK 0x5427
|
|
|
--#define TIOCCBRK 0x5428
|
|
|
--#define TIOCGSID 0x5429
|
|
|
--#define TIOCGPTN 0x80045430
|
|
|
--#define TIOCSPTLCK 0x40045431
|
|
|
--#define TCGETX 0x5432
|
|
|
--#define TCSETX 0x5433
|
|
|
--#define TCSETXF 0x5434
|
|
|
--#define TCSETXW 0x5435
|
|
|
--
|
|
|
--#define FIONCLEX 0x5450
|
|
|
--#define FIOCLEX 0x5451
|
|
|
--#define FIOASYNC 0x5452
|
|
|
--#define TIOCSERCONFIG 0x5453
|
|
|
--#define TIOCSERGWILD 0x5454
|
|
|
--#define TIOCSERSWILD 0x5455
|
|
|
--#define TIOCGLCKTRMIOS 0x5456
|
|
|
--#define TIOCSLCKTRMIOS 0x5457
|
|
|
--#define TIOCSERGSTRUCT 0x5458
|
|
|
--#define TIOCSERGETLSR 0x5459
|
|
|
--#define TIOCSERGETMULTI 0x545A
|
|
|
--#define TIOCSERSETMULTI 0x545B
|
|
|
--
|
|
|
--#define TIOCMIWAIT 0x545C
|
|
|
--#define TIOCGICOUNT 0x545D
|
|
|
--#define TIOCGHAYESESP 0x545E
|
|
|
--#define TIOCSHAYESESP 0x545F
|
|
|
--#define FIOQSIZE 0x5460
|
|
|
--
|
|
|
--#define TIOCPKT_DATA 0
|
|
|
--#define TIOCPKT_FLUSHREAD 1
|
|
|
--#define TIOCPKT_FLUSHWRITE 2
|
|
|
--#define TIOCPKT_STOP 4
|
|
|
--#define TIOCPKT_START 8
|
|
|
--#define TIOCPKT_NOSTOP 16
|
|
|
--#define TIOCPKT_DOSTOP 32
|
|
|
--#define TIOCPKT_IOCTL 64
|
|
|
--
|
|
|
--#define TIOCSER_TEMT 0x01
|
|
|
--
|
|
|
--struct winsize {
|
|
|
-- unsigned short ws_row;
|
|
|
-- unsigned short ws_col;
|
|
|
-- unsigned short ws_xpixel;
|
|
|
-- unsigned short ws_ypixel;
|
|
|
--};
|
|
|
--
|
|
|
--#define TIOCM_LE 0x001
|
|
|
--#define TIOCM_DTR 0x002
|
|
|
--#define TIOCM_RTS 0x004
|
|
|
--#define TIOCM_ST 0x008
|
|
|
--#define TIOCM_SR 0x010
|
|
|
--#define TIOCM_CTS 0x020
|
|
|
--#define TIOCM_CAR 0x040
|
|
|
--#define TIOCM_RNG 0x080
|
|
|
--#define TIOCM_DSR 0x100
|
|
|
--#define TIOCM_CD TIOCM_CAR
|
|
|
--#define TIOCM_RI TIOCM_RNG
|
|
|
--#define TIOCM_OUT1 0x2000
|
|
|
--#define TIOCM_OUT2 0x4000
|
|
|
--#define TIOCM_LOOP 0x8000
|
|
|
--#define TIOCM_MODEM_BITS TIOCM_OUT2
|
|
|
--
|
|
|
--#define N_TTY 0
|
|
|
--#define N_SLIP 1
|
|
|
--#define N_MOUSE 2
|
|
|
--#define N_PPP 3
|
|
|
--#define N_STRIP 4
|
|
|
--#define N_AX25 5
|
|
|
--#define N_X25 6
|
|
|
--#define N_6PACK 7
|
|
|
--#define N_MASC 8
|
|
|
--#define N_R3964 9
|
|
|
--#define N_PROFIBUS_FDL 10
|
|
|
--#define N_IRDA 11
|
|
|
--#define N_SMSBLOCK 12
|
|
|
--#define N_HDLC 13
|
|
|
--#define N_SYNC_PPP 14
|
|
|
--#define N_HCI 15
|
|
|
--
|
|
|
--#define FIOSETOWN 0x8901
|
|
|
--#define SIOCSPGRP 0x8902
|
|
|
--#define FIOGETOWN 0x8903
|
|
|
--#define SIOCGPGRP 0x8904
|
|
|
--#define SIOCATMARK 0x8905
|
|
|
--#define SIOCGSTAMP 0x8906
|
|
|
--
|
|
|
--#define SIOCADDRT 0x890B
|
|
|
--#define SIOCDELRT 0x890C
|
|
|
--#define SIOCRTMSG 0x890D
|
|
|
--
|
|
|
--#define SIOCGIFNAME 0x8910
|
|
|
--#define SIOCSIFLINK 0x8911
|
|
|
--#define SIOCGIFCONF 0x8912
|
|
|
--#define SIOCGIFFLAGS 0x8913
|
|
|
--#define SIOCSIFFLAGS 0x8914
|
|
|
--#define SIOCGIFADDR 0x8915
|
|
|
--#define SIOCSIFADDR 0x8916
|
|
|
--#define SIOCGIFDSTADDR 0x8917
|
|
|
--#define SIOCSIFDSTADDR 0x8918
|
|
|
--#define SIOCGIFBRDADDR 0x8919
|
|
|
--#define SIOCSIFBRDADDR 0x891a
|
|
|
--#define SIOCGIFNETMASK 0x891b
|
|
|
--#define SIOCSIFNETMASK 0x891c
|
|
|
--#define SIOCGIFMETRIC 0x891d
|
|
|
--#define SIOCSIFMETRIC 0x891e
|
|
|
--#define SIOCGIFMEM 0x891f
|
|
|
--#define SIOCSIFMEM 0x8920
|
|
|
--#define SIOCGIFMTU 0x8921
|
|
|
--#define SIOCSIFMTU 0x8922
|
|
|
--#define SIOCSIFHWADDR 0x8924
|
|
|
--#define SIOCGIFENCAP 0x8925
|
|
|
--#define SIOCSIFENCAP 0x8926
|
|
|
--#define SIOCGIFHWADDR 0x8927
|
|
|
--#define SIOCGIFSLAVE 0x8929
|
|
|
--#define SIOCSIFSLAVE 0x8930
|
|
|
--#define SIOCADDMULTI 0x8931
|
|
|
--#define SIOCDELMULTI 0x8932
|
|
|
--#define SIOCGIFINDEX 0x8933
|
|
|
--#define SIOGIFINDEX SIOCGIFINDEX
|
|
|
--#define SIOCSIFPFLAGS 0x8934
|
|
|
--#define SIOCGIFPFLAGS 0x8935
|
|
|
--#define SIOCDIFADDR 0x8936
|
|
|
--#define SIOCSIFHWBROADCAST 0x8937
|
|
|
--#define SIOCGIFCOUNT 0x8938
|
|
|
--
|
|
|
--#define SIOCGIFBR 0x8940
|
|
|
--#define SIOCSIFBR 0x8941
|
|
|
--
|
|
|
--#define SIOCGIFTXQLEN 0x8942
|
|
|
--#define SIOCSIFTXQLEN 0x8943
|
|
|
--
|
|
|
--#define SIOCDARP 0x8953
|
|
|
--#define SIOCGARP 0x8954
|
|
|
--#define SIOCSARP 0x8955
|
|
|
--
|
|
|
--#define SIOCDRARP 0x8960
|
|
|
--#define SIOCGRARP 0x8961
|
|
|
--#define SIOCSRARP 0x8962
|
|
|
--
|
|
|
--#define SIOCGIFMAP 0x8970
|
|
|
--#define SIOCSIFMAP 0x8971
|
|
|
--
|
|
|
--#define SIOCADDDLCI 0x8980
|
|
|
--#define SIOCDELDLCI 0x8981
|
|
|
--
|
|
|
--#define SIOCDEVPRIVATE 0x89F0
|
|
|
--#define SIOCPROTOPRIVATE 0x89E0
|
|
|
---- a/arch/or1k/bits/mman.h
|
|
|
-+++ b/arch/or1k/bits/mman.h
|
|
|
-@@ -37,6 +37,7 @@
|
|
|
-
|
|
|
- #define MCL_CURRENT 1
|
|
|
- #define MCL_FUTURE 2
|
|
|
-+#define MCL_ONFAULT 4
|
|
|
-
|
|
|
- #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
- #define MADV_NORMAL 0
|
|
|
---- a/arch/or1k/bits/shm.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,27 +0,0 @@
|
|
|
--#define SHMLBA 4096
|
|
|
--
|
|
|
--struct shmid_ds {
|
|
|
-- struct ipc_perm shm_perm;
|
|
|
-- size_t shm_segsz;
|
|
|
-- time_t shm_atime;
|
|
|
-- int __unused1;
|
|
|
-- time_t shm_dtime;
|
|
|
-- int __unused2;
|
|
|
-- time_t shm_ctime;
|
|
|
-- int __unused3;
|
|
|
-- pid_t shm_cpid;
|
|
|
-- pid_t shm_lpid;
|
|
|
-- unsigned long shm_nattch;
|
|
|
-- unsigned long __pad1;
|
|
|
-- unsigned long __pad2;
|
|
|
--};
|
|
|
--
|
|
|
--struct shminfo {
|
|
|
-- unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
|
|
|
--};
|
|
|
--
|
|
|
--struct shm_info {
|
|
|
-- int __used_ids;
|
|
|
-- unsigned long shm_tot, shm_rss, shm_swp;
|
|
|
-- unsigned long __swap_attempts, __swap_successes;
|
|
|
--};
|
|
|
---- a/arch/or1k/bits/socket.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,15 +0,0 @@
|
|
|
--struct msghdr {
|
|
|
-- void *msg_name;
|
|
|
-- socklen_t msg_namelen;
|
|
|
-- struct iovec *msg_iov;
|
|
|
-- int msg_iovlen;
|
|
|
-- void *msg_control;
|
|
|
-- socklen_t msg_controllen;
|
|
|
-- int msg_flags;
|
|
|
--};
|
|
|
--
|
|
|
--struct cmsghdr {
|
|
|
-- socklen_t cmsg_len;
|
|
|
-- int cmsg_level;
|
|
|
-- int cmsg_type;
|
|
|
--};
|
|
|
---- a/arch/or1k/bits/statfs.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,7 +0,0 @@
|
|
|
--struct statfs {
|
|
|
-- unsigned long f_type, f_bsize;
|
|
|
-- fsblkcnt_t f_blocks, f_bfree, f_bavail;
|
|
|
-- fsfilcnt_t f_files, f_ffree;
|
|
|
-- fsid_t f_fsid;
|
|
|
-- unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
|
|
|
--};
|
|
|
---- a/arch/or1k/bits/stdarg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,4 +0,0 @@
|
|
|
--#define va_start(v,l) __builtin_va_start(v,l)
|
|
|
--#define va_end(v) __builtin_va_end(v)
|
|
|
--#define va_arg(v,l) __builtin_va_arg(v,l)
|
|
|
--#define va_copy(d,s) __builtin_va_copy(d,s)
|
|
|
---- a/arch/or1k/bits/syscall.h
|
|
|
-+++ b/arch/or1k/bits/syscall.h
|
|
|
-@@ -265,6 +265,9 @@
|
|
|
- #define __NR_memfd_create 279
|
|
|
- #define __NR_bpf 280
|
|
|
- #define __NR_execveat 281
|
|
|
-+#define __NR_userfaultfd 282
|
|
|
-+#define __NR_membarrier 283
|
|
|
-+#define __NR_mlock2 284
|
|
|
-
|
|
|
- #define SYS_io_setup __NR_io_setup
|
|
|
- #define SYS_io_destroy __NR_io_destroy
|
|
|
-@@ -533,3 +536,6 @@
|
|
|
- #define SYS_memfd_create __NR_memfd_create
|
|
|
- #define SYS_bpf __NR_bpf
|
|
|
- #define SYS_execveat __NR_execveat
|
|
|
-+#define SYS_userfaultfd __NR_userfaultfd
|
|
|
-+#define SYS_membarrier __NR_membarrier
|
|
|
-+#define SYS_mlock2 __NR_mlock2
|
|
|
---- a/arch/or1k/bits/termios.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,159 +0,0 @@
|
|
|
--struct termios {
|
|
|
-- tcflag_t c_iflag;
|
|
|
-- tcflag_t c_oflag;
|
|
|
-- tcflag_t c_cflag;
|
|
|
-- tcflag_t c_lflag;
|
|
|
-- cc_t c_line;
|
|
|
-- cc_t c_cc[NCCS];
|
|
|
-- speed_t __c_ispeed;
|
|
|
-- speed_t __c_ospeed;
|
|
|
--};
|
|
|
--
|
|
|
--#define VINTR 0
|
|
|
--#define VQUIT 1
|
|
|
--#define VERASE 2
|
|
|
--#define VKILL 3
|
|
|
--#define VEOF 4
|
|
|
--#define VTIME 5
|
|
|
--#define VMIN 6
|
|
|
--#define VSWTC 7
|
|
|
--#define VSTART 8
|
|
|
--#define VSTOP 9
|
|
|
--#define VSUSP 10
|
|
|
--#define VEOL 11
|
|
|
--#define VREPRINT 12
|
|
|
--#define VDISCARD 13
|
|
|
--#define VWERASE 14
|
|
|
--#define VLNEXT 15
|
|
|
--#define VEOL2 16
|
|
|
--
|
|
|
--#define IGNBRK 0000001
|
|
|
--#define BRKINT 0000002
|
|
|
--#define IGNPAR 0000004
|
|
|
--#define PARMRK 0000010
|
|
|
--#define INPCK 0000020
|
|
|
--#define ISTRIP 0000040
|
|
|
--#define INLCR 0000100
|
|
|
--#define IGNCR 0000200
|
|
|
--#define ICRNL 0000400
|
|
|
--#define IUCLC 0001000
|
|
|
--#define IXON 0002000
|
|
|
--#define IXANY 0004000
|
|
|
--#define IXOFF 0010000
|
|
|
--#define IMAXBEL 0020000
|
|
|
--#define IUTF8 0040000
|
|
|
--
|
|
|
--#define OPOST 0000001
|
|
|
--#define OLCUC 0000002
|
|
|
--#define ONLCR 0000004
|
|
|
--#define OCRNL 0000010
|
|
|
--#define ONOCR 0000020
|
|
|
--#define ONLRET 0000040
|
|
|
--#define OFILL 0000100
|
|
|
--#define OFDEL 0000200
|
|
|
--#define NLDLY 0000400
|
|
|
--#define NL0 0000000
|
|
|
--#define NL1 0000400
|
|
|
--#define CRDLY 0003000
|
|
|
--#define CR0 0000000
|
|
|
--#define CR1 0001000
|
|
|
--#define CR2 0002000
|
|
|
--#define CR3 0003000
|
|
|
--#define TABDLY 0014000
|
|
|
--#define TAB0 0000000
|
|
|
--#define TAB1 0004000
|
|
|
--#define TAB2 0010000
|
|
|
--#define TAB3 0014000
|
|
|
--#define BSDLY 0020000
|
|
|
--#define BS0 0000000
|
|
|
--#define BS1 0020000
|
|
|
--#define FFDLY 0100000
|
|
|
--#define FF0 0000000
|
|
|
--#define FF1 0100000
|
|
|
--
|
|
|
--#define VTDLY 0040000
|
|
|
--#define VT0 0000000
|
|
|
--#define VT1 0040000
|
|
|
--
|
|
|
--#define B0 0000000
|
|
|
--#define B50 0000001
|
|
|
--#define B75 0000002
|
|
|
--#define B110 0000003
|
|
|
--#define B134 0000004
|
|
|
--#define B150 0000005
|
|
|
--#define B200 0000006
|
|
|
--#define B300 0000007
|
|
|
--#define B600 0000010
|
|
|
--#define B1200 0000011
|
|
|
--#define B1800 0000012
|
|
|
--#define B2400 0000013
|
|
|
--#define B4800 0000014
|
|
|
--#define B9600 0000015
|
|
|
--#define B19200 0000016
|
|
|
--#define B38400 0000017
|
|
|
--
|
|
|
--#define B57600 0010001
|
|
|
--#define B115200 0010002
|
|
|
--#define B230400 0010003
|
|
|
--#define B460800 0010004
|
|
|
--#define B500000 0010005
|
|
|
--#define B576000 0010006
|
|
|
--#define B921600 0010007
|
|
|
--#define B1000000 0010010
|
|
|
--#define B1152000 0010011
|
|
|
--#define B1500000 0010012
|
|
|
--#define B2000000 0010013
|
|
|
--#define B2500000 0010014
|
|
|
--#define B3000000 0010015
|
|
|
--#define B3500000 0010016
|
|
|
--#define B4000000 0010017
|
|
|
--
|
|
|
--#define CBAUD 0010017
|
|
|
--
|
|
|
--#define CSIZE 0000060
|
|
|
--#define CS5 0000000
|
|
|
--#define CS6 0000020
|
|
|
--#define CS7 0000040
|
|
|
--#define CS8 0000060
|
|
|
--#define CSTOPB 0000100
|
|
|
--#define CREAD 0000200
|
|
|
--#define PARENB 0000400
|
|
|
--#define PARODD 0001000
|
|
|
--#define HUPCL 0002000
|
|
|
--#define CLOCAL 0004000
|
|
|
--
|
|
|
--#define ISIG 0000001
|
|
|
--#define ICANON 0000002
|
|
|
--#define ECHO 0000010
|
|
|
--#define ECHOE 0000020
|
|
|
--#define ECHOK 0000040
|
|
|
--#define ECHONL 0000100
|
|
|
--#define NOFLSH 0000200
|
|
|
--#define TOSTOP 0000400
|
|
|
--#define IEXTEN 0100000
|
|
|
--
|
|
|
--#define ECHOCTL 0001000
|
|
|
--#define ECHOPRT 0002000
|
|
|
--#define ECHOKE 0004000
|
|
|
--#define FLUSHO 0010000
|
|
|
--#define PENDIN 0040000
|
|
|
--
|
|
|
--#define TCOOFF 0
|
|
|
--#define TCOON 1
|
|
|
--#define TCIOFF 2
|
|
|
--#define TCION 3
|
|
|
--
|
|
|
--#define TCIFLUSH 0
|
|
|
--#define TCOFLUSH 1
|
|
|
--#define TCIOFLUSH 2
|
|
|
--
|
|
|
--#define TCSANOW 0
|
|
|
--#define TCSADRAIN 1
|
|
|
--#define TCSAFLUSH 2
|
|
|
--
|
|
|
--#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
--#define CBAUDEX 0010000
|
|
|
--#define CRTSCTS 020000000000
|
|
|
--#define EXTPROC 0200000
|
|
|
--#define XTABS 0014000
|
|
|
--#endif
|
|
|
---- a/arch/or1k/pthread_arch.h
|
|
|
-+++ b/arch/or1k/pthread_arch.h
|
|
|
-@@ -14,5 +14,4 @@ static inline struct pthread *__pthread_
|
|
|
- #define TLS_ABOVE_TP
|
|
|
- #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread))
|
|
|
-
|
|
|
--/* word-offset to 'pc' in mcontext_t */
|
|
|
--#define CANCEL_REG_IP 32
|
|
|
-+#define MC_PC regs.pc
|
|
|
---- a/arch/powerpc/atomic.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,126 +0,0 @@
|
|
|
--#ifndef _INTERNAL_ATOMIC_H
|
|
|
--#define _INTERNAL_ATOMIC_H
|
|
|
--
|
|
|
--#include <stdint.h>
|
|
|
--#include <endian.h>
|
|
|
--
|
|
|
--static inline int a_ctz_l(unsigned long x)
|
|
|
--{
|
|
|
-- static const char debruijn32[32] = {
|
|
|
-- 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
|
|
|
-- 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
|
|
|
-- };
|
|
|
-- return debruijn32[(x&-x)*0x076be629 >> 27];
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_ctz_64(uint64_t x)
|
|
|
--{
|
|
|
-- uint32_t y = x;
|
|
|
-- if (!y) {
|
|
|
-- y = x>>32;
|
|
|
-- return 32 + a_ctz_l(y);
|
|
|
-- }
|
|
|
-- return a_ctz_l(y);
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_cas(volatile int *p, int t, int s)
|
|
|
--{
|
|
|
-- __asm__("\n"
|
|
|
-- " sync\n"
|
|
|
-- "1: lwarx %0, 0, %4\n"
|
|
|
-- " cmpw %0, %2\n"
|
|
|
-- " bne 1f\n"
|
|
|
-- " stwcx. %3, 0, %4\n"
|
|
|
-- " bne- 1b\n"
|
|
|
-- " isync\n"
|
|
|
-- "1: \n"
|
|
|
-- : "=&r"(t), "+m"(*p) : "r"(t), "r"(s), "r"(p) : "cc", "memory" );
|
|
|
-- return t;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
--{
|
|
|
-- return (void *)a_cas(p, (int)t, (int)s);
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_swap(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *x;
|
|
|
-- while (a_cas(x, old, v) != old);
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_fetch_add(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *x;
|
|
|
-- while (a_cas(x, old, old+v) != old);
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_inc(volatile int *x)
|
|
|
--{
|
|
|
-- a_fetch_add(x, 1);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_dec(volatile int *x)
|
|
|
--{
|
|
|
-- a_fetch_add(x, -1);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_store(volatile int *p, int x)
|
|
|
--{
|
|
|
-- __asm__ __volatile__ ("\n"
|
|
|
-- " sync\n"
|
|
|
-- " stw %1, %0\n"
|
|
|
-- " isync\n"
|
|
|
-- : "=m"(*p) : "r"(x) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--#define a_spin a_barrier
|
|
|
--
|
|
|
--static inline void a_barrier()
|
|
|
--{
|
|
|
-- a_cas(&(int){0}, 0, 0);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_crash()
|
|
|
--{
|
|
|
-- *(volatile char *)0=0;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and(volatile int *p, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *p;
|
|
|
-- while (a_cas(p, old, old&v) != old);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or(volatile int *p, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- do old = *p;
|
|
|
-- while (a_cas(p, old, old|v) != old);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_l(volatile void *p, long v)
|
|
|
--{
|
|
|
-- a_or(p, v);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-- a_and((int *)p, u.r[0]);
|
|
|
-- a_and((int *)p+1, u.r[1]);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-- a_or((int *)p, u.r[0]);
|
|
|
-- a_or((int *)p+1, u.r[1]);
|
|
|
--}
|
|
|
--
|
|
|
--#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/powerpc/atomic_arch.h
|
|
|
-@@ -0,0 +1,39 @@
|
|
|
-+#define a_ll a_ll
|
|
|
-+static inline int a_ll(volatile int *p)
|
|
|
-+{
|
|
|
-+ int v;
|
|
|
-+ __asm__ __volatile__ ("lwarx %0, 0, %2" : "=r"(v) : "m"(*p), "r"(p));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_sc a_sc
|
|
|
-+static inline int a_sc(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int r;
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ "stwcx. %2, 0, %3 ; mfcr %0"
|
|
|
-+ : "=r"(r), "=m"(*p) : "r"(v), "r"(p) : "memory", "cc");
|
|
|
-+ return r & 0x20000000; /* "bit 2" of "cr0" (backwards bit order) */
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_barrier a_barrier
|
|
|
-+static inline void a_barrier()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__ ("sync" : : : "memory");
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_pre_llsc a_barrier
|
|
|
-+
|
|
|
-+#define a_post_llsc a_post_llsc
|
|
|
-+static inline void a_post_llsc()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__ ("isync" : : : "memory");
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_store a_store
|
|
|
-+static inline void a_store(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ a_pre_llsc();
|
|
|
-+ *p = v;
|
|
|
-+ a_post_llsc();
|
|
|
-+}
|
|
|
---- a/arch/powerpc/bits/mman.h
|
|
|
-+++ b/arch/powerpc/bits/mman.h
|
|
|
-@@ -4,6 +4,7 @@
|
|
|
- #define PROT_READ 1
|
|
|
- #define PROT_WRITE 2
|
|
|
- #define PROT_EXEC 4
|
|
|
-+#define PROT_SAO 0x10
|
|
|
- #define PROT_GROWSDOWN 0x01000000
|
|
|
- #define PROT_GROWSUP 0x02000000
|
|
|
-
|
|
|
-@@ -35,8 +36,9 @@
|
|
|
- #define MS_INVALIDATE 2
|
|
|
- #define MS_SYNC 4
|
|
|
-
|
|
|
--#define MCL_CURRENT 1
|
|
|
--#define MCL_FUTURE 2
|
|
|
-+#define MCL_CURRENT 0x2000
|
|
|
-+#define MCL_FUTURE 0x4000
|
|
|
-+#define MCL_ONFAULT 0x8000
|
|
|
-
|
|
|
- #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
- #define MADV_NORMAL 0
|
|
|
---- a/arch/powerpc/bits/statfs.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,7 +0,0 @@
|
|
|
--struct statfs {
|
|
|
-- unsigned long f_type, f_bsize;
|
|
|
-- fsblkcnt_t f_blocks, f_bfree, f_bavail;
|
|
|
-- fsfilcnt_t f_files, f_ffree;
|
|
|
-- fsid_t f_fsid;
|
|
|
-- unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
|
|
|
--};
|
|
|
---- a/arch/powerpc/bits/stdarg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,4 +0,0 @@
|
|
|
--#define va_start(v,l) __builtin_va_start(v,l)
|
|
|
--#define va_end(v) __builtin_va_end(v)
|
|
|
--#define va_arg(v,l) __builtin_va_arg(v,l)
|
|
|
--#define va_copy(d,s) __builtin_va_copy(d,s)
|
|
|
---- a/arch/powerpc/bits/syscall.h
|
|
|
-+++ b/arch/powerpc/bits/syscall.h
|
|
|
-@@ -194,23 +194,19 @@
|
|
|
- #define __NR_vfork 189
|
|
|
- #define __NR_ugetrlimit 190
|
|
|
- #define __NR_readahead 191
|
|
|
--#if !defined(__PPC64) || defined(__ABI32)
|
|
|
- #define __NR_mmap2 192
|
|
|
- #define __NR_truncate64 193
|
|
|
- #define __NR_ftruncate64 194
|
|
|
- #define __NR_stat64 195
|
|
|
- #define __NR_lstat64 196
|
|
|
- #define __NR_fstat64 197
|
|
|
--#endif
|
|
|
- #define __NR_pciconfig_read 198
|
|
|
- #define __NR_pciconfig_write 199
|
|
|
- #define __NR_pciconfig_iobase 200
|
|
|
- #define __NR_multiplexer 201
|
|
|
- #define __NR_getdents64 202
|
|
|
- #define __NR_pivot_root 203
|
|
|
--#if !defined(__PPC64) || defined(__ABI32)
|
|
|
- #define __NR_fcntl64 204
|
|
|
--#endif
|
|
|
- #define __NR_madvise 205
|
|
|
- #define __NR_mincore 206
|
|
|
- #define __NR_gettid 207
|
|
|
-@@ -231,9 +227,7 @@
|
|
|
- #define __NR_sched_setaffinity 222
|
|
|
- #define __NR_sched_getaffinity 223
|
|
|
- #define __NR_tuxcall 225
|
|
|
--#if !defined(__PPC64) || defined(__ABI32)
|
|
|
- #define __NR_sendfile64 226
|
|
|
--#endif
|
|
|
- #define __NR_io_setup 227
|
|
|
- #define __NR_io_destroy 228
|
|
|
- #define __NR_io_getevents 229
|
|
|
-@@ -261,9 +255,7 @@
|
|
|
- #define __NR_utimes 251
|
|
|
- #define __NR_statfs64 252
|
|
|
- #define __NR_fstatfs64 253
|
|
|
--#if !defined(__PPC64) || defined(__ABI32)
|
|
|
- #define __NR_fadvise64_64 254
|
|
|
--#endif
|
|
|
- #define __NR_rtas 255
|
|
|
- #define __NR_sys_debug_setcontext 256
|
|
|
- #define __NR_migrate_pages 258
|
|
|
-@@ -299,11 +291,7 @@
|
|
|
- #define __NR_mknodat 288
|
|
|
- #define __NR_fchownat 289
|
|
|
- #define __NR_futimesat 290
|
|
|
--#if defined(__PPC64) && !defined(__ABI32)
|
|
|
--#define __NR_newfstatat 291
|
|
|
--#else
|
|
|
- #define __NR_fstatat64 291
|
|
|
--#endif
|
|
|
- #define __NR_unlinkat 292
|
|
|
- #define __NR_renameat 293
|
|
|
- #define __NR_linkat 294
|
|
|
-@@ -376,6 +364,10 @@
|
|
|
- #define __NR_memfd_create 360
|
|
|
- #define __NR_bpf 361
|
|
|
- #define __NR_execveat 362
|
|
|
-+#define __NR_switch_endian 363
|
|
|
-+#define __NR_userfaultfd 364
|
|
|
-+#define __NR_membarrier 365
|
|
|
-+#define __NR_mlock2 378
|
|
|
-
|
|
|
- /*
|
|
|
- * repeated with SYS prefix
|
|
|
-@@ -576,23 +568,19 @@
|
|
|
- #define SYS_vfork 189
|
|
|
- #define SYS_ugetrlimit 190
|
|
|
- #define SYS_readahead 191
|
|
|
--#if !defined(__PPC64) || defined(__ABI32)
|
|
|
- #define SYS_mmap2 192
|
|
|
- #define SYS_truncate64 193
|
|
|
- #define SYS_ftruncate64 194
|
|
|
- #define SYS_stat64 195
|
|
|
- #define SYS_lstat64 196
|
|
|
- #define SYS_fstat64 197
|
|
|
--#endif
|
|
|
- #define SYS_pciconfig_read 198
|
|
|
- #define SYS_pciconfig_write 199
|
|
|
- #define SYS_pciconfig_iobase 200
|
|
|
- #define SYS_multiplexer 201
|
|
|
- #define SYS_getdents64 202
|
|
|
- #define SYS_pivot_root 203
|
|
|
--#if !defined(__PPC64) || defined(__ABI32)
|
|
|
- #define SYS_fcntl64 204
|
|
|
--#endif
|
|
|
- #define SYS_madvise 205
|
|
|
- #define SYS_mincore 206
|
|
|
- #define SYS_gettid 207
|
|
|
-@@ -613,9 +601,7 @@
|
|
|
- #define SYS_sched_setaffinity 222
|
|
|
- #define SYS_sched_getaffinity 223
|
|
|
- #define SYS_tuxcall 225
|
|
|
--#if !defined(__PPC64) || defined(__ABI32)
|
|
|
- #define SYS_sendfile64 226
|
|
|
--#endif
|
|
|
- #define SYS_io_setup 227
|
|
|
- #define SYS_io_destroy 228
|
|
|
- #define SYS_io_getevents 229
|
|
|
-@@ -643,9 +629,7 @@
|
|
|
- #define SYS_utimes 251
|
|
|
- #define SYS_statfs64 252
|
|
|
- #define SYS_fstatfs64 253
|
|
|
--#if !defined(__PPC64) || defined(__ABI32)
|
|
|
- #define SYS_fadvise64_64 254
|
|
|
--#endif
|
|
|
- #define SYS_rtas 255
|
|
|
- #define SYS_sys_debug_setcontext 256
|
|
|
- #define SYS_migrate_pages 258
|
|
|
-@@ -681,11 +665,7 @@
|
|
|
- #define SYS_mknodat 288
|
|
|
- #define SYS_fchownat 289
|
|
|
- #define SYS_futimesat 290
|
|
|
--#if defined(__PPC64) && !defined(__ABI32)
|
|
|
--#define SYS_newfstatat 291
|
|
|
--#else
|
|
|
- #define SYS_fstatat64 291
|
|
|
--#endif
|
|
|
- #define SYS_unlinkat 292
|
|
|
- #define SYS_renameat 293
|
|
|
- #define SYS_linkat 294
|
|
|
-@@ -758,3 +738,7 @@
|
|
|
- #define SYS_memfd_create 360
|
|
|
- #define SYS_bpf 361
|
|
|
- #define SYS_execveat 362
|
|
|
-+#define SYS_switch_endian 363
|
|
|
-+#define SYS_userfaultfd 364
|
|
|
-+#define SYS_membarrier 365
|
|
|
-+#define SYS_mlock2 378
|
|
|
---- a/arch/powerpc/pthread_arch.h
|
|
|
-+++ b/arch/powerpc/pthread_arch.h
|
|
|
-@@ -15,9 +15,8 @@ static inline struct pthread *__pthread_
|
|
|
-
|
|
|
- #define DTP_OFFSET 0x8000
|
|
|
-
|
|
|
--// offset of the PC register in mcontext_t, divided by the system wordsize
|
|
|
- // the kernel calls the ip "nip", it's the first saved value after the 32
|
|
|
- // GPRs.
|
|
|
--#define CANCEL_REG_IP 32
|
|
|
-+#define MC_PC gregs[32]
|
|
|
-
|
|
|
- #define CANARY canary_at_end
|
|
|
---- a/arch/sh/atomic.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,168 +0,0 @@
|
|
|
--#ifndef _INTERNAL_ATOMIC_H
|
|
|
--#define _INTERNAL_ATOMIC_H
|
|
|
--
|
|
|
--#include <stdint.h>
|
|
|
--
|
|
|
--static inline int a_ctz_l(unsigned long x)
|
|
|
--{
|
|
|
-- static const char debruijn32[32] = {
|
|
|
-- 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
|
|
|
-- 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
|
|
|
-- };
|
|
|
-- return debruijn32[(x&-x)*0x076be629 >> 27];
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_ctz_64(uint64_t x)
|
|
|
--{
|
|
|
-- uint32_t y = x;
|
|
|
-- if (!y) {
|
|
|
-- y = x>>32;
|
|
|
-- return 32 + a_ctz_l(y);
|
|
|
-- }
|
|
|
-- return a_ctz_l(y);
|
|
|
--}
|
|
|
--
|
|
|
--#define LLSC_CLOBBERS "r0", "t", "memory"
|
|
|
--#define LLSC_START(mem) "synco\n" \
|
|
|
-- "0: movli.l @" mem ", r0\n"
|
|
|
--#define LLSC_END(mem) \
|
|
|
-- "1: movco.l r0, @" mem "\n" \
|
|
|
-- " bf 0b\n" \
|
|
|
-- " synco\n"
|
|
|
--
|
|
|
--static inline int __sh_cas_llsc(volatile int *p, int t, int s)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- LLSC_START("%1")
|
|
|
-- " mov r0, %0\n"
|
|
|
-- " cmp/eq %0, %2\n"
|
|
|
-- " bf 1f\n"
|
|
|
-- " mov %3, r0\n"
|
|
|
-- LLSC_END("%1")
|
|
|
-- : "=&r"(old) : "r"(p), "r"(t), "r"(s) : LLSC_CLOBBERS);
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int __sh_swap_llsc(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- LLSC_START("%1")
|
|
|
-- " mov r0, %0\n"
|
|
|
-- " mov %2, r0\n"
|
|
|
-- LLSC_END("%1")
|
|
|
-- : "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int __sh_fetch_add_llsc(volatile int *x, int v)
|
|
|
--{
|
|
|
-- int old;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- LLSC_START("%1")
|
|
|
-- " mov r0, %0\n"
|
|
|
-- " add %2, r0\n"
|
|
|
-- LLSC_END("%1")
|
|
|
-- : "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void __sh_store_llsc(volatile int *p, int x)
|
|
|
--{
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " synco\n"
|
|
|
-- " mov.l %1, @%0\n"
|
|
|
-- " synco\n"
|
|
|
-- : : "r"(p), "r"(x) : "memory");
|
|
|
--}
|
|
|
--
|
|
|
--static inline void __sh_and_llsc(volatile int *x, int v)
|
|
|
--{
|
|
|
-- __asm__ __volatile__(
|
|
|
-- LLSC_START("%0")
|
|
|
-- " and %1, r0\n"
|
|
|
-- LLSC_END("%0")
|
|
|
-- : : "r"(x), "r"(v) : LLSC_CLOBBERS);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void __sh_or_llsc(volatile int *x, int v)
|
|
|
--{
|
|
|
-- __asm__ __volatile__(
|
|
|
-- LLSC_START("%0")
|
|
|
-- " or %1, r0\n"
|
|
|
-- LLSC_END("%0")
|
|
|
-- : : "r"(x), "r"(v) : LLSC_CLOBBERS);
|
|
|
--}
|
|
|
--
|
|
|
--#ifdef __SH4A__
|
|
|
--#define a_cas(p,t,s) __sh_cas_llsc(p,t,s)
|
|
|
--#define a_swap(x,v) __sh_swap_llsc(x,v)
|
|
|
--#define a_fetch_add(x,v) __sh_fetch_add_llsc(x, v)
|
|
|
--#define a_store(x,v) __sh_store_llsc(x, v)
|
|
|
--#define a_and(x,v) __sh_and_llsc(x, v)
|
|
|
--#define a_or(x,v) __sh_or_llsc(x, v)
|
|
|
--#else
|
|
|
--
|
|
|
--int __sh_cas(volatile int *, int, int);
|
|
|
--int __sh_swap(volatile int *, int);
|
|
|
--int __sh_fetch_add(volatile int *, int);
|
|
|
--void __sh_store(volatile int *, int);
|
|
|
--void __sh_and(volatile int *, int);
|
|
|
--void __sh_or(volatile int *, int);
|
|
|
--
|
|
|
--#define a_cas(p,t,s) __sh_cas(p,t,s)
|
|
|
--#define a_swap(x,v) __sh_swap(x,v)
|
|
|
--#define a_fetch_add(x,v) __sh_fetch_add(x, v)
|
|
|
--#define a_store(x,v) __sh_store(x, v)
|
|
|
--#define a_and(x,v) __sh_and(x, v)
|
|
|
--#define a_or(x,v) __sh_or(x, v)
|
|
|
--#endif
|
|
|
--
|
|
|
--static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
--{
|
|
|
-- return (void *)a_cas(p, (int)t, (int)s);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_inc(volatile int *x)
|
|
|
--{
|
|
|
-- a_fetch_add(x, 1);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_dec(volatile int *x)
|
|
|
--{
|
|
|
-- a_fetch_add(x, -1);
|
|
|
--}
|
|
|
--
|
|
|
--#define a_spin a_barrier
|
|
|
--
|
|
|
--static inline void a_barrier()
|
|
|
--{
|
|
|
-- a_cas(&(int){0}, 0, 0);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_crash()
|
|
|
--{
|
|
|
-- *(volatile char *)0=0;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_l(volatile void *p, long v)
|
|
|
--{
|
|
|
-- a_or(p, v);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-- a_and((int *)p, u.r[0]);
|
|
|
-- a_and((int *)p+1, u.r[1]);
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-- a_or((int *)p, u.r[0]);
|
|
|
-- a_or((int *)p+1, u.r[1]);
|
|
|
--}
|
|
|
--
|
|
|
--#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/sh/atomic_arch.h
|
|
|
-@@ -0,0 +1,46 @@
|
|
|
-+#if defined(__SH4A__)
|
|
|
-+
|
|
|
-+#define a_ll a_ll
|
|
|
-+static inline int a_ll(volatile int *p)
|
|
|
-+{
|
|
|
-+ int v;
|
|
|
-+ __asm__ __volatile__ ("movli.l @%1, %0" : "=z"(v) : "r"(p), "m"(*p));
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_sc a_sc
|
|
|
-+static inline int a_sc(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int r;
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ "movco.l %2, @%3 ; movt %0"
|
|
|
-+ : "=r"(r), "=m"(*p) : "z"(v), "r"(p) : "memory", "cc");
|
|
|
-+ return r;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_barrier a_barrier
|
|
|
-+static inline void a_barrier()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__ ("synco" : : "memory");
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_pre_llsc a_barrier
|
|
|
-+#define a_post_llsc a_barrier
|
|
|
-+
|
|
|
-+#else
|
|
|
-+
|
|
|
-+#define a_cas a_cas
|
|
|
-+__attribute__((__visibility__("hidden"))) extern const void *__sh_cas_ptr;
|
|
|
-+static inline int a_cas(volatile int *p, int t, int s)
|
|
|
-+{
|
|
|
-+ register int r1 __asm__("r1");
|
|
|
-+ register int r2 __asm__("r2") = t;
|
|
|
-+ register int r3 __asm__("r3") = s;
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ "jsr @%4 ; nop"
|
|
|
-+ : "=r"(r1), "+r"(r3) : "z"(p), "r"(r2), "r"(__sh_cas_ptr)
|
|
|
-+ : "memory", "pr", "cc");
|
|
|
-+ return r3;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#endif
|
|
|
---- a/arch/sh/bits/errno.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,134 +0,0 @@
|
|
|
--#define EPERM 1
|
|
|
--#define ENOENT 2
|
|
|
--#define ESRCH 3
|
|
|
--#define EINTR 4
|
|
|
--#define EIO 5
|
|
|
--#define ENXIO 6
|
|
|
--#define E2BIG 7
|
|
|
--#define ENOEXEC 8
|
|
|
--#define EBADF 9
|
|
|
--#define ECHILD 10
|
|
|
--#define EAGAIN 11
|
|
|
--#define ENOMEM 12
|
|
|
--#define EACCES 13
|
|
|
--#define EFAULT 14
|
|
|
--#define ENOTBLK 15
|
|
|
--#define EBUSY 16
|
|
|
--#define EEXIST 17
|
|
|
--#define EXDEV 18
|
|
|
--#define ENODEV 19
|
|
|
--#define ENOTDIR 20
|
|
|
--#define EISDIR 21
|
|
|
--#define EINVAL 22
|
|
|
--#define ENFILE 23
|
|
|
--#define EMFILE 24
|
|
|
--#define ENOTTY 25
|
|
|
--#define ETXTBSY 26
|
|
|
--#define EFBIG 27
|
|
|
--#define ENOSPC 28
|
|
|
--#define ESPIPE 29
|
|
|
--#define EROFS 30
|
|
|
--#define EMLINK 31
|
|
|
--#define EPIPE 32
|
|
|
--#define EDOM 33
|
|
|
--#define ERANGE 34
|
|
|
--#define EDEADLK 35
|
|
|
--#define ENAMETOOLONG 36
|
|
|
--#define ENOLCK 37
|
|
|
--#define ENOSYS 38
|
|
|
--#define ENOTEMPTY 39
|
|
|
--#define ELOOP 40
|
|
|
--#define EWOULDBLOCK EAGAIN
|
|
|
--#define ENOMSG 42
|
|
|
--#define EIDRM 43
|
|
|
--#define ECHRNG 44
|
|
|
--#define EL2NSYNC 45
|
|
|
--#define EL3HLT 46
|
|
|
--#define EL3RST 47
|
|
|
--#define ELNRNG 48
|
|
|
--#define EUNATCH 49
|
|
|
--#define ENOCSI 50
|
|
|
--#define EL2HLT 51
|
|
|
--#define EBADE 52
|
|
|
--#define EBADR 53
|
|
|
--#define EXFULL 54
|
|
|
--#define ENOANO 55
|
|
|
--#define EBADRQC 56
|
|
|
--#define EBADSLT 57
|
|
|
--#define EDEADLOCK EDEADLK
|
|
|
--#define EBFONT 59
|
|
|
--#define ENOSTR 60
|
|
|
--#define ENODATA 61
|
|
|
--#define ETIME 62
|
|
|
--#define ENOSR 63
|
|
|
--#define ENONET 64
|
|
|
--#define ENOPKG 65
|
|
|
--#define EREMOTE 66
|
|
|
--#define ENOLINK 67
|
|
|
--#define EADV 68
|
|
|
--#define ESRMNT 69
|
|
|
--#define ECOMM 70
|
|
|
--#define EPROTO 71
|
|
|
--#define EMULTIHOP 72
|
|
|
--#define EDOTDOT 73
|
|
|
--#define EBADMSG 74
|
|
|
--#define EOVERFLOW 75
|
|
|
--#define ENOTUNIQ 76
|
|
|
--#define EBADFD 77
|
|
|
--#define EREMCHG 78
|
|
|
--#define ELIBACC 79
|
|
|
--#define ELIBBAD 80
|
|
|
--#define ELIBSCN 81
|
|
|
--#define ELIBMAX 82
|
|
|
--#define ELIBEXEC 83
|
|
|
--#define EILSEQ 84
|
|
|
--#define ERESTART 85
|
|
|
--#define ESTRPIPE 86
|
|
|
--#define EUSERS 87
|
|
|
--#define ENOTSOCK 88
|
|
|
--#define EDESTADDRREQ 89
|
|
|
--#define EMSGSIZE 90
|
|
|
--#define EPROTOTYPE 91
|
|
|
--#define ENOPROTOOPT 92
|
|
|
--#define EPROTONOSUPPORT 93
|
|
|
--#define ESOCKTNOSUPPORT 94
|
|
|
--#define EOPNOTSUPP 95
|
|
|
--#define ENOTSUP EOPNOTSUPP
|
|
|
--#define EPFNOSUPPORT 96
|
|
|
--#define EAFNOSUPPORT 97
|
|
|
--#define EADDRINUSE 98
|
|
|
--#define EADDRNOTAVAIL 99
|
|
|
--#define ENETDOWN 100
|
|
|
--#define ENETUNREACH 101
|
|
|
--#define ENETRESET 102
|
|
|
--#define ECONNABORTED 103
|
|
|
--#define ECONNRESET 104
|
|
|
--#define ENOBUFS 105
|
|
|
--#define EISCONN 106
|
|
|
--#define ENOTCONN 107
|
|
|
--#define ESHUTDOWN 108
|
|
|
--#define ETOOMANYREFS 109
|
|
|
--#define ETIMEDOUT 110
|
|
|
--#define ECONNREFUSED 111
|
|
|
--#define EHOSTDOWN 112
|
|
|
--#define EHOSTUNREACH 113
|
|
|
--#define EALREADY 114
|
|
|
--#define EINPROGRESS 115
|
|
|
--#define ESTALE 116
|
|
|
--#define EUCLEAN 117
|
|
|
--#define ENOTNAM 118
|
|
|
--#define ENAVAIL 119
|
|
|
--#define EISNAM 120
|
|
|
--#define EREMOTEIO 121
|
|
|
--#define EDQUOT 122
|
|
|
--#define ENOMEDIUM 123
|
|
|
--#define EMEDIUMTYPE 124
|
|
|
--#define ECANCELED 125
|
|
|
--#define ENOKEY 126
|
|
|
--#define EKEYEXPIRED 127
|
|
|
--#define EKEYREVOKED 128
|
|
|
--#define EKEYREJECTED 129
|
|
|
--#define EOWNERDEAD 130
|
|
|
--#define ENOTRECOVERABLE 131
|
|
|
--#define ERFKILL 132
|
|
|
--#define EHWPOISON 133
|
|
|
---- a/arch/sh/bits/fcntl.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,40 +0,0 @@
|
|
|
--#define O_CREAT 0100
|
|
|
--#define O_EXCL 0200
|
|
|
--#define O_NOCTTY 0400
|
|
|
--#define O_TRUNC 01000
|
|
|
--#define O_APPEND 02000
|
|
|
--#define O_NONBLOCK 04000
|
|
|
--#define O_DSYNC 010000
|
|
|
--#define O_SYNC 04010000
|
|
|
--#define O_RSYNC 04010000
|
|
|
--#define O_DIRECTORY 0200000
|
|
|
--#define O_NOFOLLOW 0400000
|
|
|
--#define O_CLOEXEC 02000000
|
|
|
--
|
|
|
--#define O_ASYNC 020000
|
|
|
--#define O_DIRECT 040000
|
|
|
--#define O_LARGEFILE 0100000
|
|
|
--#define O_NOATIME 01000000
|
|
|
--#define O_PATH 010000000
|
|
|
--#define O_TMPFILE 020200000
|
|
|
--#define O_NDELAY O_NONBLOCK
|
|
|
--
|
|
|
--#define F_DUPFD 0
|
|
|
--#define F_GETFD 1
|
|
|
--#define F_SETFD 2
|
|
|
--#define F_GETFL 3
|
|
|
--#define F_SETFL 4
|
|
|
--
|
|
|
--#define F_SETOWN 8
|
|
|
--#define F_GETOWN 9
|
|
|
--#define F_SETSIG 10
|
|
|
--#define F_GETSIG 11
|
|
|
--
|
|
|
--#define F_GETLK 12
|
|
|
--#define F_SETLK 13
|
|
|
--#define F_SETLKW 14
|
|
|
--
|
|
|
--#define F_SETOWN_EX 15
|
|
|
--#define F_GETOWN_EX 16
|
|
|
--
|
|
|
--#define F_GETOWNER_UIDS 17
|
|
|
---- a/arch/sh/bits/ipc.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,14 +0,0 @@
|
|
|
--struct ipc_perm
|
|
|
--{
|
|
|
-- key_t __ipc_perm_key;
|
|
|
-- uid_t uid;
|
|
|
-- gid_t gid;
|
|
|
-- uid_t cuid;
|
|
|
-- gid_t cgid;
|
|
|
-- mode_t mode;
|
|
|
-- int __ipc_perm_seq;
|
|
|
-- long __pad1;
|
|
|
-- long __pad2;
|
|
|
--};
|
|
|
--
|
|
|
--#define IPC_64 0x100
|
|
|
---- a/arch/sh/bits/mman.h
|
|
|
-+++ b/arch/sh/bits/mman.h
|
|
|
-@@ -38,6 +38,7 @@
|
|
|
-
|
|
|
- #define MCL_CURRENT 1
|
|
|
- #define MCL_FUTURE 2
|
|
|
-+#define MCL_ONFAULT 4
|
|
|
-
|
|
|
- #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
- #define MADV_NORMAL 0
|
|
|
---- a/arch/sh/bits/msg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,16 +0,0 @@
|
|
|
--struct msqid_ds
|
|
|
--{
|
|
|
-- struct ipc_perm msg_perm;
|
|
|
-- time_t msg_stime;
|
|
|
-- int __unused1;
|
|
|
-- time_t msg_rtime;
|
|
|
-- int __unused2;
|
|
|
-- time_t msg_ctime;
|
|
|
-- int __unused3;
|
|
|
-- unsigned long msg_cbytes;
|
|
|
-- msgqnum_t msg_qnum;
|
|
|
-- msglen_t msg_qbytes;
|
|
|
-- pid_t msg_lspid;
|
|
|
-- pid_t msg_lrpid;
|
|
|
-- unsigned long __unused[2];
|
|
|
--};
|
|
|
---- a/arch/sh/bits/sem.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,16 +0,0 @@
|
|
|
--struct semid_ds {
|
|
|
-- struct ipc_perm sem_perm;
|
|
|
-- time_t sem_otime;
|
|
|
-- time_t __unused1;
|
|
|
-- time_t sem_ctime;
|
|
|
-- time_t __unused2;
|
|
|
--#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
-- unsigned short sem_nsems;
|
|
|
-- char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
--#else
|
|
|
-- char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
-- unsigned short sem_nsems;
|
|
|
--#endif
|
|
|
-- time_t __unused3;
|
|
|
-- time_t __unused4;
|
|
|
--};
|
|
|
---- a/arch/sh/bits/socket.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,17 +0,0 @@
|
|
|
--struct msghdr
|
|
|
--{
|
|
|
-- void *msg_name;
|
|
|
-- socklen_t msg_namelen;
|
|
|
-- struct iovec *msg_iov;
|
|
|
-- int msg_iovlen;
|
|
|
-- void *msg_control;
|
|
|
-- socklen_t msg_controllen;
|
|
|
-- int msg_flags;
|
|
|
--};
|
|
|
--
|
|
|
--struct cmsghdr
|
|
|
--{
|
|
|
-- socklen_t cmsg_len;
|
|
|
-- int cmsg_level;
|
|
|
-- int cmsg_type;
|
|
|
--};
|
|
|
---- a/arch/sh/bits/statfs.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,7 +0,0 @@
|
|
|
--struct statfs {
|
|
|
-- unsigned long f_type, f_bsize;
|
|
|
-- fsblkcnt_t f_blocks, f_bfree, f_bavail;
|
|
|
-- fsfilcnt_t f_files, f_ffree;
|
|
|
-- fsid_t f_fsid;
|
|
|
-- unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
|
|
|
--};
|
|
|
---- a/arch/sh/bits/stdarg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,4 +0,0 @@
|
|
|
--#define va_start(v,l) __builtin_va_start(v,l)
|
|
|
--#define va_end(v) __builtin_va_end(v)
|
|
|
--#define va_arg(v,l) __builtin_va_arg(v,l)
|
|
|
--#define va_copy(d,s) __builtin_va_copy(d,s)
|
|
|
---- a/arch/sh/bits/termios.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,160 +0,0 @@
|
|
|
--struct termios
|
|
|
--{
|
|
|
-- tcflag_t c_iflag;
|
|
|
-- tcflag_t c_oflag;
|
|
|
-- tcflag_t c_cflag;
|
|
|
-- tcflag_t c_lflag;
|
|
|
-- cc_t c_line;
|
|
|
-- cc_t c_cc[NCCS];
|
|
|
-- speed_t __c_ispeed;
|
|
|
-- speed_t __c_ospeed;
|
|
|
--};
|
|
|
--
|
|
|
--#define VINTR 0
|
|
|
--#define VQUIT 1
|
|
|
--#define VERASE 2
|
|
|
--#define VKILL 3
|
|
|
--#define VEOF 4
|
|
|
--#define VTIME 5
|
|
|
--#define VMIN 6
|
|
|
--#define VSWTC 7
|
|
|
--#define VSTART 8
|
|
|
--#define VSTOP 9
|
|
|
--#define VSUSP 10
|
|
|
--#define VEOL 11
|
|
|
--#define VREPRINT 12
|
|
|
--#define VDISCARD 13
|
|
|
--#define VWERASE 14
|
|
|
--#define VLNEXT 15
|
|
|
--#define VEOL2 16
|
|
|
--
|
|
|
--#define IGNBRK 0000001
|
|
|
--#define BRKINT 0000002
|
|
|
--#define IGNPAR 0000004
|
|
|
--#define PARMRK 0000010
|
|
|
--#define INPCK 0000020
|
|
|
--#define ISTRIP 0000040
|
|
|
--#define INLCR 0000100
|
|
|
--#define IGNCR 0000200
|
|
|
--#define ICRNL 0000400
|
|
|
--#define IUCLC 0001000
|
|
|
--#define IXON 0002000
|
|
|
--#define IXANY 0004000
|
|
|
--#define IXOFF 0010000
|
|
|
--#define IMAXBEL 0020000
|
|
|
--#define IUTF8 0040000
|
|
|
--
|
|
|
--#define OPOST 0000001
|
|
|
--#define OLCUC 0000002
|
|
|
--#define ONLCR 0000004
|
|
|
--#define OCRNL 0000010
|
|
|
--#define ONOCR 0000020
|
|
|
--#define ONLRET 0000040
|
|
|
--#define OFILL 0000100
|
|
|
--#define OFDEL 0000200
|
|
|
--#define NLDLY 0000400
|
|
|
--#define NL0 0000000
|
|
|
--#define NL1 0000400
|
|
|
--#define CRDLY 0003000
|
|
|
--#define CR0 0000000
|
|
|
--#define CR1 0001000
|
|
|
--#define CR2 0002000
|
|
|
--#define CR3 0003000
|
|
|
--#define TABDLY 0014000
|
|
|
--#define TAB0 0000000
|
|
|
--#define TAB1 0004000
|
|
|
--#define TAB2 0010000
|
|
|
--#define TAB3 0014000
|
|
|
--#define BSDLY 0020000
|
|
|
--#define BS0 0000000
|
|
|
--#define BS1 0020000
|
|
|
--#define FFDLY 0100000
|
|
|
--#define FF0 0000000
|
|
|
--#define FF1 0100000
|
|
|
--
|
|
|
--#define VTDLY 0040000
|
|
|
--#define VT0 0000000
|
|
|
--#define VT1 0040000
|
|
|
--
|
|
|
--#define B0 0000000
|
|
|
--#define B50 0000001
|
|
|
--#define B75 0000002
|
|
|
--#define B110 0000003
|
|
|
--#define B134 0000004
|
|
|
--#define B150 0000005
|
|
|
--#define B200 0000006
|
|
|
--#define B300 0000007
|
|
|
--#define B600 0000010
|
|
|
--#define B1200 0000011
|
|
|
--#define B1800 0000012
|
|
|
--#define B2400 0000013
|
|
|
--#define B4800 0000014
|
|
|
--#define B9600 0000015
|
|
|
--#define B19200 0000016
|
|
|
--#define B38400 0000017
|
|
|
--
|
|
|
--#define B57600 0010001
|
|
|
--#define B115200 0010002
|
|
|
--#define B230400 0010003
|
|
|
--#define B460800 0010004
|
|
|
--#define B500000 0010005
|
|
|
--#define B576000 0010006
|
|
|
--#define B921600 0010007
|
|
|
--#define B1000000 0010010
|
|
|
--#define B1152000 0010011
|
|
|
--#define B1500000 0010012
|
|
|
--#define B2000000 0010013
|
|
|
--#define B2500000 0010014
|
|
|
--#define B3000000 0010015
|
|
|
--#define B3500000 0010016
|
|
|
--#define B4000000 0010017
|
|
|
--
|
|
|
--#define CBAUD 0010017
|
|
|
--
|
|
|
--#define CSIZE 0000060
|
|
|
--#define CS5 0000000
|
|
|
--#define CS6 0000020
|
|
|
--#define CS7 0000040
|
|
|
--#define CS8 0000060
|
|
|
--#define CSTOPB 0000100
|
|
|
--#define CREAD 0000200
|
|
|
--#define PARENB 0000400
|
|
|
--#define PARODD 0001000
|
|
|
--#define HUPCL 0002000
|
|
|
--#define CLOCAL 0004000
|
|
|
--
|
|
|
--#define ISIG 0000001
|
|
|
--#define ICANON 0000002
|
|
|
--#define ECHO 0000010
|
|
|
--#define ECHOE 0000020
|
|
|
--#define ECHOK 0000040
|
|
|
--#define ECHONL 0000100
|
|
|
--#define NOFLSH 0000200
|
|
|
--#define TOSTOP 0000400
|
|
|
--#define IEXTEN 0100000
|
|
|
--
|
|
|
--#define ECHOCTL 0001000
|
|
|
--#define ECHOPRT 0002000
|
|
|
--#define ECHOKE 0004000
|
|
|
--#define FLUSHO 0010000
|
|
|
--#define PENDIN 0040000
|
|
|
--
|
|
|
--#define TCOOFF 0
|
|
|
--#define TCOON 1
|
|
|
--#define TCIOFF 2
|
|
|
--#define TCION 3
|
|
|
--
|
|
|
--#define TCIFLUSH 0
|
|
|
--#define TCOFLUSH 1
|
|
|
--#define TCIOFLUSH 2
|
|
|
--
|
|
|
--#define TCSANOW 0
|
|
|
--#define TCSADRAIN 1
|
|
|
--#define TCSAFLUSH 2
|
|
|
--
|
|
|
--#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
--#define CBAUDEX 0010000
|
|
|
--#define CRTSCTS 020000000000
|
|
|
--#define EXTPROC 0200000
|
|
|
--#define XTABS 0014000
|
|
|
--#endif
|
|
|
---- a/arch/sh/crt_arch.h
|
|
|
-+++ b/arch/sh/crt_arch.h
|
|
|
-@@ -22,7 +22,8 @@ START ": \n"
|
|
|
- " mov.l 1f, r5 \n"
|
|
|
- " mov.l 1f+4, r6 \n"
|
|
|
- " add r0, r5 \n"
|
|
|
--" bsr __fdpic_fixup \n"
|
|
|
-+" mov.l 4f, r1 \n"
|
|
|
-+"5: bsrf r1 \n"
|
|
|
- " add r0, r6 \n"
|
|
|
- " mov r0, r12 \n"
|
|
|
- #endif
|
|
|
-@@ -31,11 +32,16 @@ START ": \n"
|
|
|
- " mov.l r9, @-r15 \n"
|
|
|
- " mov.l r8, @-r15 \n"
|
|
|
- " mov #-16, r0 \n"
|
|
|
--" bsr " START "_c \n"
|
|
|
-+" mov.l 2f, r1 \n"
|
|
|
-+"3: bsrf r1 \n"
|
|
|
- " and r0, r15 \n"
|
|
|
- ".align 2 \n"
|
|
|
- "1: .long __ROFIXUP_LIST__@PCREL \n"
|
|
|
- " .long __ROFIXUP_END__@PCREL + 4 \n"
|
|
|
-+"2: .long " START "_c@PCREL - (3b+4-.) \n"
|
|
|
-+#ifndef SHARED
|
|
|
-+"4: .long __fdpic_fixup@PCREL - (5b+4-.) \n"
|
|
|
-+#endif
|
|
|
- );
|
|
|
-
|
|
|
- #ifndef SHARED
|
|
|
-@@ -53,13 +59,14 @@ START ": \n"
|
|
|
- " add r0, r5 \n"
|
|
|
- " mov r15, r4 \n"
|
|
|
- " mov #-16, r0 \n"
|
|
|
--" and r0, r15 \n"
|
|
|
--" bsr " START "_c \n"
|
|
|
--" nop \n"
|
|
|
-+" mov.l 2f, r1 \n"
|
|
|
-+"3: bsrf r1 \n"
|
|
|
-+" and r0, r15 \n"
|
|
|
- ".align 2 \n"
|
|
|
- ".weak _DYNAMIC \n"
|
|
|
- ".hidden _DYNAMIC \n"
|
|
|
- "1: .long _DYNAMIC-. \n"
|
|
|
-+"2: .long " START "_c@PCREL - (3b+4-.) \n"
|
|
|
- );
|
|
|
-
|
|
|
- #endif
|
|
|
---- a/arch/sh/pthread_arch.h
|
|
|
-+++ b/arch/sh/pthread_arch.h
|
|
|
-@@ -8,4 +8,4 @@ static inline struct pthread *__pthread_
|
|
|
- #define TLS_ABOVE_TP
|
|
|
- #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 8)
|
|
|
-
|
|
|
--#define CANCEL_REG_IP 17
|
|
|
-+#define MC_PC sc_pc
|
|
|
---- a/arch/sh/reloc.h
|
|
|
-+++ b/arch/sh/reloc.h
|
|
|
-@@ -32,6 +32,8 @@
|
|
|
- #define REL_DTPOFF R_SH_TLS_DTPOFF32
|
|
|
- #define REL_TPOFF R_SH_TLS_TPOFF32
|
|
|
-
|
|
|
-+#define DL_NOMMU_SUPPORT 1
|
|
|
-+
|
|
|
- #if __SH_FDPIC__
|
|
|
- #define REL_FUNCDESC R_SH_FUNCDESC
|
|
|
- #define REL_FUNCDESC_VAL R_SH_FUNCDESC_VALUE
|
|
|
---- a/arch/sh/src/__fpscr_values.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,5 +0,0 @@
|
|
|
--#include "libc.h"
|
|
|
--
|
|
|
--/* used by gcc for switching the FPU between single and double precision */
|
|
|
--//const unsigned long __fpscr_values[2] ATTR_LIBC_VISIBILITY = { 0, 0x80000 };
|
|
|
--
|
|
|
---- a/arch/sh/src/__set_thread_area.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,34 +0,0 @@
|
|
|
--#include "pthread_impl.h"
|
|
|
--#include "libc.h"
|
|
|
--#include "sh_atomic.h"
|
|
|
--#include <elf.h>
|
|
|
--
|
|
|
--/* Also perform sh-specific init */
|
|
|
--
|
|
|
--#define CPU_HAS_LLSC 0x0040
|
|
|
--
|
|
|
--__attribute__((__visibility__("hidden"))) unsigned __sh_atomic_model, __sh_nommu;
|
|
|
--
|
|
|
--int __set_thread_area(void *p)
|
|
|
--{
|
|
|
-- size_t *aux;
|
|
|
-- __asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
|
|
|
--#ifndef __SH4A__
|
|
|
-- if (__hwcap & CPU_HAS_LLSC) {
|
|
|
-- __sh_atomic_model = SH_A_LLSC;
|
|
|
-- return 0;
|
|
|
-- }
|
|
|
--#if !defined(__SH3__) && !defined(__SH4__)
|
|
|
-- for (aux=libc.auxv; *aux; aux+=2) {
|
|
|
-- if (*aux != AT_PLATFORM) continue;
|
|
|
-- const char *s = (void *)aux[1];
|
|
|
-- if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
|
|
|
-- __sh_atomic_model = SH_A_IMASK;
|
|
|
-- __sh_nommu = 1;
|
|
|
-- return 0;
|
|
|
-- }
|
|
|
--#endif
|
|
|
-- /* __sh_atomic_model = SH_A_GUSA; */ /* 0, default */
|
|
|
--#endif
|
|
|
-- return 0;
|
|
|
--}
|
|
|
---- a/arch/sh/src/__shcall.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,5 +0,0 @@
|
|
|
--__attribute__((__visibility__("hidden")))
|
|
|
--int __shcall(void *arg, int (*func)(void *))
|
|
|
--{
|
|
|
-- return func(arg);
|
|
|
--}
|
|
|
---- a/arch/sh/src/__unmapself.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,24 +0,0 @@
|
|
|
--#include "pthread_impl.h"
|
|
|
--
|
|
|
--void __unmapself_sh_mmu(void *, size_t);
|
|
|
--void __unmapself_sh_nommu(void *, size_t);
|
|
|
--
|
|
|
--#if !defined(__SH3__) && !defined(__SH4__)
|
|
|
--#define __unmapself __unmapself_sh_nommu
|
|
|
--#include "dynlink.h"
|
|
|
--#undef CRTJMP
|
|
|
--#define CRTJMP(pc,sp) __asm__ __volatile__( \
|
|
|
-- "mov.l @%0+,r0 ; mov.l @%0,r12 ; jmp @r0 ; mov %1,r15" \
|
|
|
-- : : "r"(pc), "r"(sp) : "r0", "memory" )
|
|
|
--#include "../../../src/thread/__unmapself.c"
|
|
|
--#undef __unmapself
|
|
|
--extern __attribute__((__visibility__("hidden"))) unsigned __sh_nommu;
|
|
|
--#else
|
|
|
--#define __sh_nommu 0
|
|
|
--#endif
|
|
|
--
|
|
|
--void __unmapself(void *base, size_t size)
|
|
|
--{
|
|
|
-- if (__sh_nommu) __unmapself_sh_nommu(base, size);
|
|
|
-- else __unmapself_sh_mmu(base, size);
|
|
|
--}
|
|
|
---- a/arch/sh/src/atomic.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,158 +0,0 @@
|
|
|
--#ifndef __SH4A__
|
|
|
--
|
|
|
--#include "sh_atomic.h"
|
|
|
--#include "atomic.h"
|
|
|
--#include "libc.h"
|
|
|
--
|
|
|
--static inline unsigned mask()
|
|
|
--{
|
|
|
-- unsigned sr;
|
|
|
-- __asm__ __volatile__ ( "\n"
|
|
|
-- " stc sr,r0 \n"
|
|
|
-- " mov r0,%0 \n"
|
|
|
-- " or #0xf0,r0 \n"
|
|
|
-- " ldc r0,sr \n"
|
|
|
-- : "=&r"(sr) : : "memory", "r0" );
|
|
|
-- return sr;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void unmask(unsigned sr)
|
|
|
--{
|
|
|
-- __asm__ __volatile__ ( "ldc %0,sr" : : "r"(sr) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--/* gusa is a hack in the kernel which lets you create a sequence of instructions
|
|
|
-- * which will be restarted if the process is preempted in the middle of the
|
|
|
-- * sequence. It will do for implementing atomics on non-smp systems. ABI is:
|
|
|
-- * r0 = address of first instruction after the atomic sequence
|
|
|
-- * r1 = original stack pointer
|
|
|
-- * r15 = -1 * length of atomic sequence in bytes
|
|
|
-- */
|
|
|
--#define GUSA_CLOBBERS "r0", "r1", "memory"
|
|
|
--#define GUSA_START(mem,old,nop) \
|
|
|
-- " .align 2\n" \
|
|
|
-- " mova 1f, r0\n" \
|
|
|
-- nop \
|
|
|
-- " mov r15, r1\n" \
|
|
|
-- " mov #(0f-1f), r15\n" \
|
|
|
-- "0: mov.l @" mem ", " old "\n"
|
|
|
--/* the target of mova must be 4 byte aligned, so we may need a nop */
|
|
|
--#define GUSA_START_ODD(mem,old) GUSA_START(mem,old,"")
|
|
|
--#define GUSA_START_EVEN(mem,old) GUSA_START(mem,old,"\tnop\n")
|
|
|
--#define GUSA_END(mem,new) \
|
|
|
-- " mov.l " new ", @" mem "\n" \
|
|
|
-- "1: mov r1, r15\n"
|
|
|
--
|
|
|
--int __sh_cas(volatile int *p, int t, int s)
|
|
|
--{
|
|
|
-- if (__sh_atomic_model == SH_A_LLSC) return __sh_cas_llsc(p, t, s);
|
|
|
--
|
|
|
-- if (__sh_atomic_model == SH_A_IMASK) {
|
|
|
-- unsigned sr = mask();
|
|
|
-- int old = *p;
|
|
|
-- if (old==t) *p = s;
|
|
|
-- unmask(sr);
|
|
|
-- return old;
|
|
|
-- }
|
|
|
--
|
|
|
-- int old;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- GUSA_START_EVEN("%1", "%0")
|
|
|
-- " cmp/eq %0, %2\n"
|
|
|
-- " bf 1f\n"
|
|
|
-- GUSA_END("%1", "%3")
|
|
|
-- : "=&r"(old) : "r"(p), "r"(t), "r"(s) : GUSA_CLOBBERS, "t");
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--int __sh_swap(volatile int *x, int v)
|
|
|
--{
|
|
|
-- if (__sh_atomic_model == SH_A_LLSC) return __sh_swap_llsc(x, v);
|
|
|
--
|
|
|
-- if (__sh_atomic_model == SH_A_IMASK) {
|
|
|
-- unsigned sr = mask();
|
|
|
-- int old = *x;
|
|
|
-- *x = v;
|
|
|
-- unmask(sr);
|
|
|
-- return old;
|
|
|
-- }
|
|
|
--
|
|
|
-- int old;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- GUSA_START_EVEN("%1", "%0")
|
|
|
-- GUSA_END("%1", "%2")
|
|
|
-- : "=&r"(old) : "r"(x), "r"(v) : GUSA_CLOBBERS);
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--int __sh_fetch_add(volatile int *x, int v)
|
|
|
--{
|
|
|
-- if (__sh_atomic_model == SH_A_LLSC) return __sh_fetch_add_llsc(x, v);
|
|
|
--
|
|
|
-- if (__sh_atomic_model == SH_A_IMASK) {
|
|
|
-- unsigned sr = mask();
|
|
|
-- int old = *x;
|
|
|
-- *x = old + v;
|
|
|
-- unmask(sr);
|
|
|
-- return old;
|
|
|
-- }
|
|
|
--
|
|
|
-- int old, dummy;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- GUSA_START_EVEN("%2", "%0")
|
|
|
-- " mov %0, %1\n"
|
|
|
-- " add %3, %1\n"
|
|
|
-- GUSA_END("%2", "%1")
|
|
|
-- : "=&r"(old), "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
|
|
|
-- return old;
|
|
|
--}
|
|
|
--
|
|
|
--void __sh_store(volatile int *p, int x)
|
|
|
--{
|
|
|
-- if (__sh_atomic_model == SH_A_LLSC) return __sh_store_llsc(p, x);
|
|
|
-- __asm__ __volatile__(
|
|
|
-- " mov.l %1, @%0\n"
|
|
|
-- : : "r"(p), "r"(x) : "memory");
|
|
|
--}
|
|
|
--
|
|
|
--void __sh_and(volatile int *x, int v)
|
|
|
--{
|
|
|
-- if (__sh_atomic_model == SH_A_LLSC) return __sh_and_llsc(x, v);
|
|
|
--
|
|
|
-- if (__sh_atomic_model == SH_A_IMASK) {
|
|
|
-- unsigned sr = mask();
|
|
|
-- int old = *x;
|
|
|
-- *x = old & v;
|
|
|
-- unmask(sr);
|
|
|
-- return;
|
|
|
-- }
|
|
|
--
|
|
|
-- int dummy;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- GUSA_START_ODD("%1", "%0")
|
|
|
-- " and %2, %0\n"
|
|
|
-- GUSA_END("%1", "%0")
|
|
|
-- : "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
|
|
|
--}
|
|
|
--
|
|
|
--void __sh_or(volatile int *x, int v)
|
|
|
--{
|
|
|
-- if (__sh_atomic_model == SH_A_LLSC) return __sh_or_llsc(x, v);
|
|
|
--
|
|
|
-- if (__sh_atomic_model == SH_A_IMASK) {
|
|
|
-- unsigned sr = mask();
|
|
|
-- int old = *x;
|
|
|
-- *x = old | v;
|
|
|
-- unmask(sr);
|
|
|
-- return;
|
|
|
-- }
|
|
|
--
|
|
|
-- int dummy;
|
|
|
-- __asm__ __volatile__(
|
|
|
-- GUSA_START_ODD("%1", "%0")
|
|
|
-- " or %2, %0\n"
|
|
|
-- GUSA_END("%1", "%0")
|
|
|
-- : "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
|
|
|
--}
|
|
|
--
|
|
|
--#endif
|
|
|
---- a/arch/sh/src/sh_atomic.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,15 +0,0 @@
|
|
|
--#ifndef _SH_ATOMIC_H
|
|
|
--#define _SH_ATOMIC_H
|
|
|
--
|
|
|
--#define SH_A_GUSA 0
|
|
|
--#define SH_A_LLSC 1
|
|
|
--#define SH_A_CAS 2
|
|
|
--#if !defined(__SH3__) && !defined(__SH4__)
|
|
|
--#define SH_A_IMASK 3
|
|
|
--#else
|
|
|
--#define SH_A_IMASK -1LL /* unmatchable by unsigned int */
|
|
|
--#endif
|
|
|
--
|
|
|
--extern __attribute__((__visibility__("hidden"))) unsigned __sh_atomic_model;
|
|
|
--
|
|
|
--#endif
|
|
|
---- a/arch/x32/atomic.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,105 +0,0 @@
|
|
|
--#ifndef _INTERNAL_ATOMIC_H
|
|
|
--#define _INTERNAL_ATOMIC_H
|
|
|
--
|
|
|
--#include <stdint.h>
|
|
|
--
|
|
|
--static inline int a_ctz_64(uint64_t x)
|
|
|
--{
|
|
|
-- __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
|
|
|
-- return x;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_ctz_l(unsigned long x)
|
|
|
--{
|
|
|
-- __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
|
|
|
-- return x;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; and %1, %0"
|
|
|
-- : "=m"(*p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; or %1, %0"
|
|
|
-- : "=m"(*p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_l(volatile void *p, long v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; or %1, %0"
|
|
|
-- : "=m"(*(long *)p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
--{
|
|
|
-- __asm__( "lock ; cmpxchg %3, %1"
|
|
|
-- : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
|
|
|
-- return t;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_cas(volatile int *p, int t, int s)
|
|
|
--{
|
|
|
-- __asm__( "lock ; cmpxchg %3, %1"
|
|
|
-- : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
|
|
|
-- return t;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or(volatile int *p, int v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; or %1, %0"
|
|
|
-- : "=m"(*p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and(volatile int *p, int v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; and %1, %0"
|
|
|
-- : "=m"(*p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_swap(volatile int *x, int v)
|
|
|
--{
|
|
|
-- __asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
|
|
|
-- return v;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_fetch_add(volatile int *x, int v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
|
|
|
-- return v;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_inc(volatile int *x)
|
|
|
--{
|
|
|
-- __asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_dec(volatile int *x)
|
|
|
--{
|
|
|
-- __asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_store(volatile int *p, int x)
|
|
|
--{
|
|
|
-- __asm__( "mov %1, %0 ; lock ; orl $0,(%%rsp)" : "=m"(*p) : "r"(x) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_spin()
|
|
|
--{
|
|
|
-- __asm__ __volatile__( "pause" : : : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_barrier()
|
|
|
--{
|
|
|
-- __asm__ __volatile__( "" : : : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_crash()
|
|
|
--{
|
|
|
-- __asm__ __volatile__( "hlt" : : : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--
|
|
|
--#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/x32/atomic_arch.h
|
|
|
-@@ -0,0 +1,114 @@
|
|
|
-+#define a_cas a_cas
|
|
|
-+static inline int a_cas(volatile int *p, int t, int s)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ "lock ; cmpxchg %3, %1"
|
|
|
-+ : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
|
|
|
-+ return t;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_swap a_swap
|
|
|
-+static inline int a_swap(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "xchg %0, %1"
|
|
|
-+ : "=r"(v), "=m"(*p) : "0"(v) : "memory" );
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_fetch_add a_fetch_add
|
|
|
-+static inline int a_fetch_add(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; xadd %0, %1"
|
|
|
-+ : "=r"(v), "=m"(*p) : "0"(v) : "memory" );
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_and a_and
|
|
|
-+static inline void a_and(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; and %1, %0"
|
|
|
-+ : "=m"(*p) : "r"(v) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_or a_or
|
|
|
-+static inline void a_or(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; or %1, %0"
|
|
|
-+ : "=m"(*p) : "r"(v) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_and_64 a_and_64
|
|
|
-+static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile(
|
|
|
-+ "lock ; and %1, %0"
|
|
|
-+ : "=m"(*p) : "r"(v) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_or_64 a_or_64
|
|
|
-+static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; or %1, %0"
|
|
|
-+ : "=m"(*p) : "r"(v) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_inc a_inc
|
|
|
-+static inline void a_inc(volatile int *p)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; incl %0"
|
|
|
-+ : "=m"(*p) : "m"(*p) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_dec a_dec
|
|
|
-+static inline void a_dec(volatile int *p)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; decl %0"
|
|
|
-+ : "=m"(*p) : "m"(*p) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_store a_store
|
|
|
-+static inline void a_store(volatile int *p, int x)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "mov %1, %0 ; lock ; orl $0,(%%rsp)"
|
|
|
-+ : "=m"(*p) : "r"(x) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_barrier a_barrier
|
|
|
-+static inline void a_barrier()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__( "" : : : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_pause a_pause
|
|
|
-+static inline void a_spin()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__( "pause" : : : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_crash a_crash
|
|
|
-+static inline void a_crash()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__( "hlt" : : : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_ctz_64 a_ctz_64
|
|
|
-+static inline int a_ctz_64(uint64_t x)
|
|
|
-+{
|
|
|
-+ __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
|
|
|
-+ return x;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_ctz_l a_ctz_l
|
|
|
-+static inline int a_ctz_l(unsigned long x)
|
|
|
-+{
|
|
|
-+ __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
|
|
|
-+ return x;
|
|
|
-+}
|
|
|
---- a/arch/x32/bits/errno.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,134 +0,0 @@
|
|
|
--#define EPERM 1
|
|
|
--#define ENOENT 2
|
|
|
--#define ESRCH 3
|
|
|
--#define EINTR 4
|
|
|
--#define EIO 5
|
|
|
--#define ENXIO 6
|
|
|
--#define E2BIG 7
|
|
|
--#define ENOEXEC 8
|
|
|
--#define EBADF 9
|
|
|
--#define ECHILD 10
|
|
|
--#define EAGAIN 11
|
|
|
--#define ENOMEM 12
|
|
|
--#define EACCES 13
|
|
|
--#define EFAULT 14
|
|
|
--#define ENOTBLK 15
|
|
|
--#define EBUSY 16
|
|
|
--#define EEXIST 17
|
|
|
--#define EXDEV 18
|
|
|
--#define ENODEV 19
|
|
|
--#define ENOTDIR 20
|
|
|
--#define EISDIR 21
|
|
|
--#define EINVAL 22
|
|
|
--#define ENFILE 23
|
|
|
--#define EMFILE 24
|
|
|
--#define ENOTTY 25
|
|
|
--#define ETXTBSY 26
|
|
|
--#define EFBIG 27
|
|
|
--#define ENOSPC 28
|
|
|
--#define ESPIPE 29
|
|
|
--#define EROFS 30
|
|
|
--#define EMLINK 31
|
|
|
--#define EPIPE 32
|
|
|
--#define EDOM 33
|
|
|
--#define ERANGE 34
|
|
|
--#define EDEADLK 35
|
|
|
--#define ENAMETOOLONG 36
|
|
|
--#define ENOLCK 37
|
|
|
--#define ENOSYS 38
|
|
|
--#define ENOTEMPTY 39
|
|
|
--#define ELOOP 40
|
|
|
--#define EWOULDBLOCK EAGAIN
|
|
|
--#define ENOMSG 42
|
|
|
--#define EIDRM 43
|
|
|
--#define ECHRNG 44
|
|
|
--#define EL2NSYNC 45
|
|
|
--#define EL3HLT 46
|
|
|
--#define EL3RST 47
|
|
|
--#define ELNRNG 48
|
|
|
--#define EUNATCH 49
|
|
|
--#define ENOCSI 50
|
|
|
--#define EL2HLT 51
|
|
|
--#define EBADE 52
|
|
|
--#define EBADR 53
|
|
|
--#define EXFULL 54
|
|
|
--#define ENOANO 55
|
|
|
--#define EBADRQC 56
|
|
|
--#define EBADSLT 57
|
|
|
--#define EDEADLOCK EDEADLK
|
|
|
--#define EBFONT 59
|
|
|
--#define ENOSTR 60
|
|
|
--#define ENODATA 61
|
|
|
--#define ETIME 62
|
|
|
--#define ENOSR 63
|
|
|
--#define ENONET 64
|
|
|
--#define ENOPKG 65
|
|
|
--#define EREMOTE 66
|
|
|
--#define ENOLINK 67
|
|
|
--#define EADV 68
|
|
|
--#define ESRMNT 69
|
|
|
--#define ECOMM 70
|
|
|
--#define EPROTO 71
|
|
|
--#define EMULTIHOP 72
|
|
|
--#define EDOTDOT 73
|
|
|
--#define EBADMSG 74
|
|
|
--#define EOVERFLOW 75
|
|
|
--#define ENOTUNIQ 76
|
|
|
--#define EBADFD 77
|
|
|
--#define EREMCHG 78
|
|
|
--#define ELIBACC 79
|
|
|
--#define ELIBBAD 80
|
|
|
--#define ELIBSCN 81
|
|
|
--#define ELIBMAX 82
|
|
|
--#define ELIBEXEC 83
|
|
|
--#define EILSEQ 84
|
|
|
--#define ERESTART 85
|
|
|
--#define ESTRPIPE 86
|
|
|
--#define EUSERS 87
|
|
|
--#define ENOTSOCK 88
|
|
|
--#define EDESTADDRREQ 89
|
|
|
--#define EMSGSIZE 90
|
|
|
--#define EPROTOTYPE 91
|
|
|
--#define ENOPROTOOPT 92
|
|
|
--#define EPROTONOSUPPORT 93
|
|
|
--#define ESOCKTNOSUPPORT 94
|
|
|
--#define EOPNOTSUPP 95
|
|
|
--#define ENOTSUP EOPNOTSUPP
|
|
|
--#define EPFNOSUPPORT 96
|
|
|
--#define EAFNOSUPPORT 97
|
|
|
--#define EADDRINUSE 98
|
|
|
--#define EADDRNOTAVAIL 99
|
|
|
--#define ENETDOWN 100
|
|
|
--#define ENETUNREACH 101
|
|
|
--#define ENETRESET 102
|
|
|
--#define ECONNABORTED 103
|
|
|
--#define ECONNRESET 104
|
|
|
--#define ENOBUFS 105
|
|
|
--#define EISCONN 106
|
|
|
--#define ENOTCONN 107
|
|
|
--#define ESHUTDOWN 108
|
|
|
--#define ETOOMANYREFS 109
|
|
|
--#define ETIMEDOUT 110
|
|
|
--#define ECONNREFUSED 111
|
|
|
--#define EHOSTDOWN 112
|
|
|
--#define EHOSTUNREACH 113
|
|
|
--#define EALREADY 114
|
|
|
--#define EINPROGRESS 115
|
|
|
--#define ESTALE 116
|
|
|
--#define EUCLEAN 117
|
|
|
--#define ENOTNAM 118
|
|
|
--#define ENAVAIL 119
|
|
|
--#define EISNAM 120
|
|
|
--#define EREMOTEIO 121
|
|
|
--#define EDQUOT 122
|
|
|
--#define ENOMEDIUM 123
|
|
|
--#define EMEDIUMTYPE 124
|
|
|
--#define ECANCELED 125
|
|
|
--#define ENOKEY 126
|
|
|
--#define EKEYEXPIRED 127
|
|
|
--#define EKEYREVOKED 128
|
|
|
--#define EKEYREJECTED 129
|
|
|
--#define EOWNERDEAD 130
|
|
|
--#define ENOTRECOVERABLE 131
|
|
|
--#define ERFKILL 132
|
|
|
--#define EHWPOISON 133
|
|
|
---- a/arch/x32/bits/mman.h
|
|
|
-+++ b/arch/x32/bits/mman.h
|
|
|
-@@ -38,6 +38,7 @@
|
|
|
-
|
|
|
- #define MCL_CURRENT 1
|
|
|
- #define MCL_FUTURE 2
|
|
|
-+#define MCL_ONFAULT 4
|
|
|
-
|
|
|
- #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
- #define MADV_NORMAL 0
|
|
|
---- a/arch/x32/bits/sem.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,16 +0,0 @@
|
|
|
--struct semid_ds {
|
|
|
-- struct ipc_perm sem_perm;
|
|
|
-- time_t sem_otime;
|
|
|
-- time_t __unused1;
|
|
|
-- time_t sem_ctime;
|
|
|
-- time_t __unused2;
|
|
|
--#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
-- unsigned short sem_nsems;
|
|
|
-- char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
--#else
|
|
|
-- char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
-- unsigned short sem_nsems;
|
|
|
--#endif
|
|
|
-- time_t __unused3;
|
|
|
-- time_t __unused4;
|
|
|
--};
|
|
|
---- a/arch/x32/bits/stdarg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,4 +0,0 @@
|
|
|
--#define va_start(v,l) __builtin_va_start(v,l)
|
|
|
--#define va_end(v) __builtin_va_end(v)
|
|
|
--#define va_arg(v,l) __builtin_va_arg(v,l)
|
|
|
--#define va_copy(d,s) __builtin_va_copy(d,s)
|
|
|
---- a/arch/x32/bits/syscall.h
|
|
|
-+++ b/arch/x32/bits/syscall.h
|
|
|
-@@ -277,6 +277,9 @@
|
|
|
- #define __NR_memfd_create (__X32_SYSCALL_BIT + 319)
|
|
|
- #define __NR_kexec_file_load (__X32_SYSCALL_BIT + 320)
|
|
|
- #define __NR_bpf (__X32_SYSCALL_BIT + 321)
|
|
|
-+#define __NR_userfaultfd (__X32_SYSCALL_BIT + 323)
|
|
|
-+#define __NR_membarrier (__X32_SYSCALL_BIT + 324)
|
|
|
-+#define __NR_mlock2 (__X32_SYSCALL_BIT + 325)
|
|
|
-
|
|
|
- #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512)
|
|
|
- #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513)
|
|
|
-@@ -607,6 +610,9 @@
|
|
|
- #define SYS_memfd_create __NR_memfd_create
|
|
|
- #define SYS_kexec_file_load __NR_kexec_file_load
|
|
|
- #define SYS_bpf __NR_bpf
|
|
|
-+#define SYS_userfaultfd __NR_userfaultfd
|
|
|
-+#define SYS_membarrier __NR_membarrier
|
|
|
-+#define SYS_mlock2 __NR_mlock2
|
|
|
-
|
|
|
-
|
|
|
- #define SYS_rt_sigaction __NR_rt_sigaction
|
|
|
---- a/arch/x32/bits/termios.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,160 +0,0 @@
|
|
|
--struct termios
|
|
|
--{
|
|
|
-- tcflag_t c_iflag;
|
|
|
-- tcflag_t c_oflag;
|
|
|
-- tcflag_t c_cflag;
|
|
|
-- tcflag_t c_lflag;
|
|
|
-- cc_t c_line;
|
|
|
-- cc_t c_cc[NCCS];
|
|
|
-- speed_t __c_ispeed;
|
|
|
-- speed_t __c_ospeed;
|
|
|
--};
|
|
|
--
|
|
|
--#define VINTR 0
|
|
|
--#define VQUIT 1
|
|
|
--#define VERASE 2
|
|
|
--#define VKILL 3
|
|
|
--#define VEOF 4
|
|
|
--#define VTIME 5
|
|
|
--#define VMIN 6
|
|
|
--#define VSWTC 7
|
|
|
--#define VSTART 8
|
|
|
--#define VSTOP 9
|
|
|
--#define VSUSP 10
|
|
|
--#define VEOL 11
|
|
|
--#define VREPRINT 12
|
|
|
--#define VDISCARD 13
|
|
|
--#define VWERASE 14
|
|
|
--#define VLNEXT 15
|
|
|
--#define VEOL2 16
|
|
|
--
|
|
|
--#define IGNBRK 0000001
|
|
|
--#define BRKINT 0000002
|
|
|
--#define IGNPAR 0000004
|
|
|
--#define PARMRK 0000010
|
|
|
--#define INPCK 0000020
|
|
|
--#define ISTRIP 0000040
|
|
|
--#define INLCR 0000100
|
|
|
--#define IGNCR 0000200
|
|
|
--#define ICRNL 0000400
|
|
|
--#define IUCLC 0001000
|
|
|
--#define IXON 0002000
|
|
|
--#define IXANY 0004000
|
|
|
--#define IXOFF 0010000
|
|
|
--#define IMAXBEL 0020000
|
|
|
--#define IUTF8 0040000
|
|
|
--
|
|
|
--#define OPOST 0000001
|
|
|
--#define OLCUC 0000002
|
|
|
--#define ONLCR 0000004
|
|
|
--#define OCRNL 0000010
|
|
|
--#define ONOCR 0000020
|
|
|
--#define ONLRET 0000040
|
|
|
--#define OFILL 0000100
|
|
|
--#define OFDEL 0000200
|
|
|
--#define NLDLY 0000400
|
|
|
--#define NL0 0000000
|
|
|
--#define NL1 0000400
|
|
|
--#define CRDLY 0003000
|
|
|
--#define CR0 0000000
|
|
|
--#define CR1 0001000
|
|
|
--#define CR2 0002000
|
|
|
--#define CR3 0003000
|
|
|
--#define TABDLY 0014000
|
|
|
--#define TAB0 0000000
|
|
|
--#define TAB1 0004000
|
|
|
--#define TAB2 0010000
|
|
|
--#define TAB3 0014000
|
|
|
--#define BSDLY 0020000
|
|
|
--#define BS0 0000000
|
|
|
--#define BS1 0020000
|
|
|
--#define FFDLY 0100000
|
|
|
--#define FF0 0000000
|
|
|
--#define FF1 0100000
|
|
|
--
|
|
|
--#define VTDLY 0040000
|
|
|
--#define VT0 0000000
|
|
|
--#define VT1 0040000
|
|
|
--
|
|
|
--#define B0 0000000
|
|
|
--#define B50 0000001
|
|
|
--#define B75 0000002
|
|
|
--#define B110 0000003
|
|
|
--#define B134 0000004
|
|
|
--#define B150 0000005
|
|
|
--#define B200 0000006
|
|
|
--#define B300 0000007
|
|
|
--#define B600 0000010
|
|
|
--#define B1200 0000011
|
|
|
--#define B1800 0000012
|
|
|
--#define B2400 0000013
|
|
|
--#define B4800 0000014
|
|
|
--#define B9600 0000015
|
|
|
--#define B19200 0000016
|
|
|
--#define B38400 0000017
|
|
|
--
|
|
|
--#define B57600 0010001
|
|
|
--#define B115200 0010002
|
|
|
--#define B230400 0010003
|
|
|
--#define B460800 0010004
|
|
|
--#define B500000 0010005
|
|
|
--#define B576000 0010006
|
|
|
--#define B921600 0010007
|
|
|
--#define B1000000 0010010
|
|
|
--#define B1152000 0010011
|
|
|
--#define B1500000 0010012
|
|
|
--#define B2000000 0010013
|
|
|
--#define B2500000 0010014
|
|
|
--#define B3000000 0010015
|
|
|
--#define B3500000 0010016
|
|
|
--#define B4000000 0010017
|
|
|
--
|
|
|
--#define CBAUD 0010017
|
|
|
--
|
|
|
--#define CSIZE 0000060
|
|
|
--#define CS5 0000000
|
|
|
--#define CS6 0000020
|
|
|
--#define CS7 0000040
|
|
|
--#define CS8 0000060
|
|
|
--#define CSTOPB 0000100
|
|
|
--#define CREAD 0000200
|
|
|
--#define PARENB 0000400
|
|
|
--#define PARODD 0001000
|
|
|
--#define HUPCL 0002000
|
|
|
--#define CLOCAL 0004000
|
|
|
--
|
|
|
--#define ISIG 0000001
|
|
|
--#define ICANON 0000002
|
|
|
--#define ECHO 0000010
|
|
|
--#define ECHOE 0000020
|
|
|
--#define ECHOK 0000040
|
|
|
--#define ECHONL 0000100
|
|
|
--#define NOFLSH 0000200
|
|
|
--#define TOSTOP 0000400
|
|
|
--#define IEXTEN 0100000
|
|
|
--
|
|
|
--#define ECHOCTL 0001000
|
|
|
--#define ECHOPRT 0002000
|
|
|
--#define ECHOKE 0004000
|
|
|
--#define FLUSHO 0010000
|
|
|
--#define PENDIN 0040000
|
|
|
--
|
|
|
--#define TCOOFF 0
|
|
|
--#define TCOON 1
|
|
|
--#define TCIOFF 2
|
|
|
--#define TCION 3
|
|
|
--
|
|
|
--#define TCIFLUSH 0
|
|
|
--#define TCOFLUSH 1
|
|
|
--#define TCIOFLUSH 2
|
|
|
--
|
|
|
--#define TCSANOW 0
|
|
|
--#define TCSADRAIN 1
|
|
|
--#define TCSAFLUSH 2
|
|
|
--
|
|
|
--#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
--#define CBAUDEX 0010000
|
|
|
--#define CRTSCTS 020000000000
|
|
|
--#define EXTPROC 0200000
|
|
|
--#define XTABS 0014000
|
|
|
--#endif
|
|
|
---- a/arch/x32/pthread_arch.h
|
|
|
-+++ b/arch/x32/pthread_arch.h
|
|
|
-@@ -7,6 +7,6 @@ static inline struct pthread *__pthread_
|
|
|
-
|
|
|
- #define TP_ADJ(p) (p)
|
|
|
-
|
|
|
--#define CANCEL_REG_IP 32
|
|
|
-+#define MC_PC gregs[REG_RIP]
|
|
|
-
|
|
|
- #define CANARY canary2
|
|
|
---- a/arch/x32/src/syscall_cp_fixup.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,42 +0,0 @@
|
|
|
--#include <sys/syscall.h>
|
|
|
--
|
|
|
--#ifdef SHARED
|
|
|
--__attribute__((__visibility__("hidden")))
|
|
|
--#endif
|
|
|
--long __syscall_cp_internal(volatile void*, long long, long long, long long, long long,
|
|
|
-- long long, long long, long long);
|
|
|
--
|
|
|
--struct __timespec { long long tv_sec; long tv_nsec; };
|
|
|
--struct __timespec_kernel { long long tv_sec; long long tv_nsec; };
|
|
|
--#define __tsc(X) ((struct __timespec*)(unsigned long)(X))
|
|
|
--#define __fixup(X) do { if(X) { \
|
|
|
-- ts->tv_sec = __tsc(X)->tv_sec; \
|
|
|
-- ts->tv_nsec = __tsc(X)->tv_nsec; \
|
|
|
-- (X) = (unsigned long)ts; } } while(0)
|
|
|
--
|
|
|
--#ifdef SHARED
|
|
|
--__attribute__((__visibility__("hidden")))
|
|
|
--#endif
|
|
|
--long __syscall_cp_asm (volatile void * foo, long long n, long long a1, long long a2, long long a3,
|
|
|
-- long long a4, long long a5, long long a6)
|
|
|
--{
|
|
|
-- struct __timespec_kernel ts[1];
|
|
|
-- switch (n) {
|
|
|
-- case SYS_mq_timedsend: case SYS_mq_timedreceive: case SYS_pselect6:
|
|
|
-- __fixup(a5);
|
|
|
-- break;
|
|
|
-- case SYS_futex:
|
|
|
-- if((a2 & (~128 /* FUTEX_PRIVATE_FLAG */)) == 0 /* FUTEX_WAIT */)
|
|
|
-- __fixup(a4);
|
|
|
-- break;
|
|
|
-- case SYS_clock_nanosleep:
|
|
|
-- case SYS_rt_sigtimedwait: case SYS_ppoll:
|
|
|
-- __fixup(a3);
|
|
|
-- break;
|
|
|
-- case SYS_nanosleep:
|
|
|
-- __fixup(a1);
|
|
|
-- break;
|
|
|
-- }
|
|
|
-- return __syscall_cp_internal(foo, n, a1, a2, a3, a4, a5, a6);
|
|
|
--}
|
|
|
--
|
|
|
---- a/arch/x32/src/sysinfo.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,50 +0,0 @@
|
|
|
--#include <sys/sysinfo.h>
|
|
|
--#include "syscall.h"
|
|
|
--#include "libc.h"
|
|
|
--
|
|
|
--#define klong long long
|
|
|
--#define kulong unsigned long long
|
|
|
--
|
|
|
--struct kernel_sysinfo {
|
|
|
-- klong uptime;
|
|
|
-- kulong loads[3];
|
|
|
-- kulong totalram;
|
|
|
-- kulong freeram;
|
|
|
-- kulong sharedram;
|
|
|
-- kulong bufferram;
|
|
|
-- kulong totalswap;
|
|
|
-- kulong freeswap;
|
|
|
-- short procs;
|
|
|
-- short pad;
|
|
|
-- kulong totalhigh;
|
|
|
-- kulong freehigh;
|
|
|
-- unsigned mem_unit;
|
|
|
--};
|
|
|
--
|
|
|
--int __lsysinfo(struct sysinfo *info)
|
|
|
--{
|
|
|
-- struct kernel_sysinfo tmp;
|
|
|
-- int ret = syscall(SYS_sysinfo, &tmp);
|
|
|
-- if(ret == -1) return ret;
|
|
|
-- info->uptime = tmp.uptime;
|
|
|
-- info->loads[0] = tmp.loads[0];
|
|
|
-- info->loads[1] = tmp.loads[1];
|
|
|
-- info->loads[2] = tmp.loads[2];
|
|
|
-- kulong shifts;
|
|
|
-- kulong max = tmp.totalram | tmp.totalswap;
|
|
|
-- __asm__("bsr %1,%0" : "=r"(shifts) : "r"(max));
|
|
|
-- shifts = shifts >= 32 ? shifts - 31 : 0;
|
|
|
-- info->totalram = tmp.totalram >> shifts;
|
|
|
-- info->freeram = tmp.freeram >> shifts;
|
|
|
-- info->sharedram = tmp.sharedram >> shifts;
|
|
|
-- info->bufferram = tmp.bufferram >> shifts;
|
|
|
-- info->totalswap = tmp.totalswap >> shifts;
|
|
|
-- info->freeswap = tmp.freeswap >> shifts;
|
|
|
-- info->procs = tmp.procs ;
|
|
|
-- info->totalhigh = tmp.totalhigh >> shifts;
|
|
|
-- info->freehigh = tmp.freehigh >> shifts;
|
|
|
-- info->mem_unit = (tmp.mem_unit ? tmp.mem_unit : 1) << shifts;
|
|
|
-- return ret;
|
|
|
--}
|
|
|
--
|
|
|
--weak_alias(__lsysinfo, sysinfo);
|
|
|
---- a/arch/x86_64/atomic.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,105 +0,0 @@
|
|
|
--#ifndef _INTERNAL_ATOMIC_H
|
|
|
--#define _INTERNAL_ATOMIC_H
|
|
|
--
|
|
|
--#include <stdint.h>
|
|
|
--
|
|
|
--static inline int a_ctz_64(uint64_t x)
|
|
|
--{
|
|
|
-- __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
|
|
|
-- return x;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_ctz_l(unsigned long x)
|
|
|
--{
|
|
|
-- __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
|
|
|
-- return x;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; and %1, %0"
|
|
|
-- : "=m"(*p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; or %1, %0"
|
|
|
-- : "=m"(*p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or_l(volatile void *p, long v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; or %1, %0"
|
|
|
-- : "=m"(*(long *)p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
--{
|
|
|
-- __asm__( "lock ; cmpxchg %3, %1"
|
|
|
-- : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
|
|
|
-- return t;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_cas(volatile int *p, int t, int s)
|
|
|
--{
|
|
|
-- __asm__( "lock ; cmpxchg %3, %1"
|
|
|
-- : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
|
|
|
-- return t;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_or(volatile int *p, int v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; or %1, %0"
|
|
|
-- : "=m"(*p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_and(volatile int *p, int v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; and %1, %0"
|
|
|
-- : "=m"(*p) : "r"(v) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_swap(volatile int *x, int v)
|
|
|
--{
|
|
|
-- __asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
|
|
|
-- return v;
|
|
|
--}
|
|
|
--
|
|
|
--static inline int a_fetch_add(volatile int *x, int v)
|
|
|
--{
|
|
|
-- __asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
|
|
|
-- return v;
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_inc(volatile int *x)
|
|
|
--{
|
|
|
-- __asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_dec(volatile int *x)
|
|
|
--{
|
|
|
-- __asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_store(volatile int *p, int x)
|
|
|
--{
|
|
|
-- __asm__( "mov %1, %0 ; lock ; orl $0,(%%rsp)" : "=m"(*p) : "r"(x) : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_spin()
|
|
|
--{
|
|
|
-- __asm__ __volatile__( "pause" : : : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_barrier()
|
|
|
--{
|
|
|
-- __asm__ __volatile__( "" : : : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--static inline void a_crash()
|
|
|
--{
|
|
|
-- __asm__ __volatile__( "hlt" : : : "memory" );
|
|
|
--}
|
|
|
--
|
|
|
--
|
|
|
--#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/arch/x86_64/atomic_arch.h
|
|
|
-@@ -0,0 +1,116 @@
|
|
|
-+#define a_cas a_cas
|
|
|
-+static inline int a_cas(volatile int *p, int t, int s)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__ (
|
|
|
-+ "lock ; cmpxchg %3, %1"
|
|
|
-+ : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
|
|
|
-+ return t;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_cas_p a_cas_p
|
|
|
-+static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
-+{
|
|
|
-+ __asm__( "lock ; cmpxchg %3, %1"
|
|
|
-+ : "=a"(t), "=m"(*(void *volatile *)p)
|
|
|
-+ : "a"(t), "r"(s) : "memory" );
|
|
|
-+ return t;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_swap a_swap
|
|
|
-+static inline int a_swap(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "xchg %0, %1"
|
|
|
-+ : "=r"(v), "=m"(*p) : "0"(v) : "memory" );
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_fetch_add a_fetch_add
|
|
|
-+static inline int a_fetch_add(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; xadd %0, %1"
|
|
|
-+ : "=r"(v), "=m"(*p) : "0"(v) : "memory" );
|
|
|
-+ return v;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_and a_and
|
|
|
-+static inline void a_and(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; and %1, %0"
|
|
|
-+ : "=m"(*p) : "r"(v) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_or a_or
|
|
|
-+static inline void a_or(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; or %1, %0"
|
|
|
-+ : "=m"(*p) : "r"(v) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_and_64 a_and_64
|
|
|
-+static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile(
|
|
|
-+ "lock ; and %1, %0"
|
|
|
-+ : "=m"(*p) : "r"(v) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_or_64 a_or_64
|
|
|
-+static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; or %1, %0"
|
|
|
-+ : "=m"(*p) : "r"(v) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_inc a_inc
|
|
|
-+static inline void a_inc(volatile int *p)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; incl %0"
|
|
|
-+ : "=m"(*p) : "m"(*p) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_dec a_dec
|
|
|
-+static inline void a_dec(volatile int *p)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "lock ; decl %0"
|
|
|
-+ : "=m"(*p) : "m"(*p) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_store a_store
|
|
|
-+static inline void a_store(volatile int *p, int x)
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__(
|
|
|
-+ "mov %1, %0 ; lock ; orl $0,(%%rsp)"
|
|
|
-+ : "=m"(*p) : "r"(x) : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_barrier a_barrier
|
|
|
-+static inline void a_barrier()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__( "" : : : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_pause a_pause
|
|
|
-+static inline void a_spin()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__( "pause" : : : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_crash a_crash
|
|
|
-+static inline void a_crash()
|
|
|
-+{
|
|
|
-+ __asm__ __volatile__( "hlt" : : : "memory" );
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define a_ctz_64 a_ctz_64
|
|
|
-+static inline int a_ctz_64(uint64_t x)
|
|
|
-+{
|
|
|
-+ __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
|
|
|
-+ return x;
|
|
|
-+}
|
|
|
---- a/arch/x86_64/bits/errno.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,134 +0,0 @@
|
|
|
--#define EPERM 1
|
|
|
--#define ENOENT 2
|
|
|
--#define ESRCH 3
|
|
|
--#define EINTR 4
|
|
|
--#define EIO 5
|
|
|
--#define ENXIO 6
|
|
|
--#define E2BIG 7
|
|
|
--#define ENOEXEC 8
|
|
|
--#define EBADF 9
|
|
|
--#define ECHILD 10
|
|
|
--#define EAGAIN 11
|
|
|
--#define ENOMEM 12
|
|
|
--#define EACCES 13
|
|
|
--#define EFAULT 14
|
|
|
--#define ENOTBLK 15
|
|
|
--#define EBUSY 16
|
|
|
--#define EEXIST 17
|
|
|
--#define EXDEV 18
|
|
|
--#define ENODEV 19
|
|
|
--#define ENOTDIR 20
|
|
|
--#define EISDIR 21
|
|
|
--#define EINVAL 22
|
|
|
--#define ENFILE 23
|
|
|
--#define EMFILE 24
|
|
|
--#define ENOTTY 25
|
|
|
--#define ETXTBSY 26
|
|
|
--#define EFBIG 27
|
|
|
--#define ENOSPC 28
|
|
|
--#define ESPIPE 29
|
|
|
--#define EROFS 30
|
|
|
--#define EMLINK 31
|
|
|
--#define EPIPE 32
|
|
|
--#define EDOM 33
|
|
|
--#define ERANGE 34
|
|
|
--#define EDEADLK 35
|
|
|
--#define ENAMETOOLONG 36
|
|
|
--#define ENOLCK 37
|
|
|
--#define ENOSYS 38
|
|
|
--#define ENOTEMPTY 39
|
|
|
--#define ELOOP 40
|
|
|
--#define EWOULDBLOCK EAGAIN
|
|
|
--#define ENOMSG 42
|
|
|
--#define EIDRM 43
|
|
|
--#define ECHRNG 44
|
|
|
--#define EL2NSYNC 45
|
|
|
--#define EL3HLT 46
|
|
|
--#define EL3RST 47
|
|
|
--#define ELNRNG 48
|
|
|
--#define EUNATCH 49
|
|
|
--#define ENOCSI 50
|
|
|
--#define EL2HLT 51
|
|
|
--#define EBADE 52
|
|
|
--#define EBADR 53
|
|
|
--#define EXFULL 54
|
|
|
--#define ENOANO 55
|
|
|
--#define EBADRQC 56
|
|
|
--#define EBADSLT 57
|
|
|
--#define EDEADLOCK EDEADLK
|
|
|
--#define EBFONT 59
|
|
|
--#define ENOSTR 60
|
|
|
--#define ENODATA 61
|
|
|
--#define ETIME 62
|
|
|
--#define ENOSR 63
|
|
|
--#define ENONET 64
|
|
|
--#define ENOPKG 65
|
|
|
--#define EREMOTE 66
|
|
|
--#define ENOLINK 67
|
|
|
--#define EADV 68
|
|
|
--#define ESRMNT 69
|
|
|
--#define ECOMM 70
|
|
|
--#define EPROTO 71
|
|
|
--#define EMULTIHOP 72
|
|
|
--#define EDOTDOT 73
|
|
|
--#define EBADMSG 74
|
|
|
--#define EOVERFLOW 75
|
|
|
--#define ENOTUNIQ 76
|
|
|
--#define EBADFD 77
|
|
|
--#define EREMCHG 78
|
|
|
--#define ELIBACC 79
|
|
|
--#define ELIBBAD 80
|
|
|
--#define ELIBSCN 81
|
|
|
--#define ELIBMAX 82
|
|
|
--#define ELIBEXEC 83
|
|
|
--#define EILSEQ 84
|
|
|
--#define ERESTART 85
|
|
|
--#define ESTRPIPE 86
|
|
|
--#define EUSERS 87
|
|
|
--#define ENOTSOCK 88
|
|
|
--#define EDESTADDRREQ 89
|
|
|
--#define EMSGSIZE 90
|
|
|
--#define EPROTOTYPE 91
|
|
|
--#define ENOPROTOOPT 92
|
|
|
--#define EPROTONOSUPPORT 93
|
|
|
--#define ESOCKTNOSUPPORT 94
|
|
|
--#define EOPNOTSUPP 95
|
|
|
--#define ENOTSUP EOPNOTSUPP
|
|
|
--#define EPFNOSUPPORT 96
|
|
|
--#define EAFNOSUPPORT 97
|
|
|
--#define EADDRINUSE 98
|
|
|
--#define EADDRNOTAVAIL 99
|
|
|
--#define ENETDOWN 100
|
|
|
--#define ENETUNREACH 101
|
|
|
--#define ENETRESET 102
|
|
|
--#define ECONNABORTED 103
|
|
|
--#define ECONNRESET 104
|
|
|
--#define ENOBUFS 105
|
|
|
--#define EISCONN 106
|
|
|
--#define ENOTCONN 107
|
|
|
--#define ESHUTDOWN 108
|
|
|
--#define ETOOMANYREFS 109
|
|
|
--#define ETIMEDOUT 110
|
|
|
--#define ECONNREFUSED 111
|
|
|
--#define EHOSTDOWN 112
|
|
|
--#define EHOSTUNREACH 113
|
|
|
--#define EALREADY 114
|
|
|
--#define EINPROGRESS 115
|
|
|
--#define ESTALE 116
|
|
|
--#define EUCLEAN 117
|
|
|
--#define ENOTNAM 118
|
|
|
--#define ENAVAIL 119
|
|
|
--#define EISNAM 120
|
|
|
--#define EREMOTEIO 121
|
|
|
--#define EDQUOT 122
|
|
|
--#define ENOMEDIUM 123
|
|
|
--#define EMEDIUMTYPE 124
|
|
|
--#define ECANCELED 125
|
|
|
--#define ENOKEY 126
|
|
|
--#define EKEYEXPIRED 127
|
|
|
--#define EKEYREVOKED 128
|
|
|
--#define EKEYREJECTED 129
|
|
|
--#define EOWNERDEAD 130
|
|
|
--#define ENOTRECOVERABLE 131
|
|
|
--#define ERFKILL 132
|
|
|
--#define EHWPOISON 133
|
|
|
---- a/arch/x86_64/bits/mman.h
|
|
|
-+++ b/arch/x86_64/bits/mman.h
|
|
|
-@@ -38,6 +38,7 @@
|
|
|
-
|
|
|
- #define MCL_CURRENT 1
|
|
|
- #define MCL_FUTURE 2
|
|
|
-+#define MCL_ONFAULT 4
|
|
|
-
|
|
|
- #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
- #define MADV_NORMAL 0
|
|
|
---- a/arch/x86_64/bits/sem.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,16 +0,0 @@
|
|
|
--struct semid_ds {
|
|
|
-- struct ipc_perm sem_perm;
|
|
|
-- time_t sem_otime;
|
|
|
-- time_t __unused1;
|
|
|
-- time_t sem_ctime;
|
|
|
-- time_t __unused2;
|
|
|
--#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
-- unsigned short sem_nsems;
|
|
|
-- char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
--#else
|
|
|
-- char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
|
|
-- unsigned short sem_nsems;
|
|
|
--#endif
|
|
|
-- time_t __unused3;
|
|
|
-- time_t __unused4;
|
|
|
--};
|
|
|
---- a/arch/x86_64/bits/statfs.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,7 +0,0 @@
|
|
|
--struct statfs {
|
|
|
-- unsigned long f_type, f_bsize;
|
|
|
-- fsblkcnt_t f_blocks, f_bfree, f_bavail;
|
|
|
-- fsfilcnt_t f_files, f_ffree;
|
|
|
-- fsid_t f_fsid;
|
|
|
-- unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
|
|
|
--};
|
|
|
---- a/arch/x86_64/bits/stdarg.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,4 +0,0 @@
|
|
|
--#define va_start(v,l) __builtin_va_start(v,l)
|
|
|
--#define va_end(v) __builtin_va_end(v)
|
|
|
--#define va_arg(v,l) __builtin_va_arg(v,l)
|
|
|
--#define va_copy(d,s) __builtin_va_copy(d,s)
|
|
|
---- a/arch/x86_64/bits/syscall.h
|
|
|
-+++ b/arch/x86_64/bits/syscall.h
|
|
|
-@@ -321,6 +321,9 @@
|
|
|
- #define __NR_kexec_file_load 320
|
|
|
- #define __NR_bpf 321
|
|
|
- #define __NR_execveat 322
|
|
|
-+#define __NR_userfaultfd 323
|
|
|
-+#define __NR_membarrier 324
|
|
|
-+#define __NR_mlock2 325
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-@@ -649,3 +652,6 @@
|
|
|
- #define SYS_kexec_file_load 320
|
|
|
- #define SYS_bpf 321
|
|
|
- #define SYS_execveat 322
|
|
|
-+#define SYS_userfaultfd 323
|
|
|
-+#define SYS_membarrier 324
|
|
|
-+#define SYS_mlock2 325
|
|
|
---- a/arch/x86_64/bits/termios.h
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,160 +0,0 @@
|
|
|
--struct termios
|
|
|
--{
|
|
|
-- tcflag_t c_iflag;
|
|
|
-- tcflag_t c_oflag;
|
|
|
-- tcflag_t c_cflag;
|
|
|
-- tcflag_t c_lflag;
|
|
|
-- cc_t c_line;
|
|
|
-- cc_t c_cc[NCCS];
|
|
|
-- speed_t __c_ispeed;
|
|
|
-- speed_t __c_ospeed;
|
|
|
--};
|
|
|
--
|
|
|
--#define VINTR 0
|
|
|
--#define VQUIT 1
|
|
|
--#define VERASE 2
|
|
|
--#define VKILL 3
|
|
|
--#define VEOF 4
|
|
|
--#define VTIME 5
|
|
|
--#define VMIN 6
|
|
|
--#define VSWTC 7
|
|
|
--#define VSTART 8
|
|
|
--#define VSTOP 9
|
|
|
--#define VSUSP 10
|
|
|
--#define VEOL 11
|
|
|
--#define VREPRINT 12
|
|
|
--#define VDISCARD 13
|
|
|
--#define VWERASE 14
|
|
|
--#define VLNEXT 15
|
|
|
--#define VEOL2 16
|
|
|
--
|
|
|
--#define IGNBRK 0000001
|
|
|
--#define BRKINT 0000002
|
|
|
--#define IGNPAR 0000004
|
|
|
--#define PARMRK 0000010
|
|
|
--#define INPCK 0000020
|
|
|
--#define ISTRIP 0000040
|
|
|
--#define INLCR 0000100
|
|
|
--#define IGNCR 0000200
|
|
|
--#define ICRNL 0000400
|
|
|
--#define IUCLC 0001000
|
|
|
--#define IXON 0002000
|
|
|
--#define IXANY 0004000
|
|
|
--#define IXOFF 0010000
|
|
|
--#define IMAXBEL 0020000
|
|
|
--#define IUTF8 0040000
|
|
|
--
|
|
|
--#define OPOST 0000001
|
|
|
--#define OLCUC 0000002
|
|
|
--#define ONLCR 0000004
|
|
|
--#define OCRNL 0000010
|
|
|
--#define ONOCR 0000020
|
|
|
--#define ONLRET 0000040
|
|
|
--#define OFILL 0000100
|
|
|
--#define OFDEL 0000200
|
|
|
--#define NLDLY 0000400
|
|
|
--#define NL0 0000000
|
|
|
--#define NL1 0000400
|
|
|
--#define CRDLY 0003000
|
|
|
--#define CR0 0000000
|
|
|
--#define CR1 0001000
|
|
|
--#define CR2 0002000
|
|
|
--#define CR3 0003000
|
|
|
--#define TABDLY 0014000
|
|
|
--#define TAB0 0000000
|
|
|
--#define TAB1 0004000
|
|
|
--#define TAB2 0010000
|
|
|
--#define TAB3 0014000
|
|
|
--#define BSDLY 0020000
|
|
|
--#define BS0 0000000
|
|
|
--#define BS1 0020000
|
|
|
--#define FFDLY 0100000
|
|
|
--#define FF0 0000000
|
|
|
--#define FF1 0100000
|
|
|
--
|
|
|
--#define VTDLY 0040000
|
|
|
--#define VT0 0000000
|
|
|
--#define VT1 0040000
|
|
|
--
|
|
|
--#define B0 0000000
|
|
|
--#define B50 0000001
|
|
|
--#define B75 0000002
|
|
|
--#define B110 0000003
|
|
|
--#define B134 0000004
|
|
|
--#define B150 0000005
|
|
|
--#define B200 0000006
|
|
|
--#define B300 0000007
|
|
|
--#define B600 0000010
|
|
|
--#define B1200 0000011
|
|
|
--#define B1800 0000012
|
|
|
--#define B2400 0000013
|
|
|
--#define B4800 0000014
|
|
|
--#define B9600 0000015
|
|
|
--#define B19200 0000016
|
|
|
--#define B38400 0000017
|
|
|
--
|
|
|
--#define B57600 0010001
|
|
|
--#define B115200 0010002
|
|
|
--#define B230400 0010003
|
|
|
--#define B460800 0010004
|
|
|
--#define B500000 0010005
|
|
|
--#define B576000 0010006
|
|
|
--#define B921600 0010007
|
|
|
--#define B1000000 0010010
|
|
|
--#define B1152000 0010011
|
|
|
--#define B1500000 0010012
|
|
|
--#define B2000000 0010013
|
|
|
--#define B2500000 0010014
|
|
|
--#define B3000000 0010015
|
|
|
--#define B3500000 0010016
|
|
|
--#define B4000000 0010017
|
|
|
--
|
|
|
--#define CBAUD 0010017
|
|
|
--
|
|
|
--#define CSIZE 0000060
|
|
|
--#define CS5 0000000
|
|
|
--#define CS6 0000020
|
|
|
--#define CS7 0000040
|
|
|
--#define CS8 0000060
|
|
|
--#define CSTOPB 0000100
|
|
|
--#define CREAD 0000200
|
|
|
--#define PARENB 0000400
|
|
|
--#define PARODD 0001000
|
|
|
--#define HUPCL 0002000
|
|
|
--#define CLOCAL 0004000
|
|
|
--
|
|
|
--#define ISIG 0000001
|
|
|
--#define ICANON 0000002
|
|
|
--#define ECHO 0000010
|
|
|
--#define ECHOE 0000020
|
|
|
--#define ECHOK 0000040
|
|
|
--#define ECHONL 0000100
|
|
|
--#define NOFLSH 0000200
|
|
|
--#define TOSTOP 0000400
|
|
|
--#define IEXTEN 0100000
|
|
|
--
|
|
|
--#define ECHOCTL 0001000
|
|
|
--#define ECHOPRT 0002000
|
|
|
--#define ECHOKE 0004000
|
|
|
--#define FLUSHO 0010000
|
|
|
--#define PENDIN 0040000
|
|
|
--
|
|
|
--#define TCOOFF 0
|
|
|
--#define TCOON 1
|
|
|
--#define TCIOFF 2
|
|
|
--#define TCION 3
|
|
|
--
|
|
|
--#define TCIFLUSH 0
|
|
|
--#define TCOFLUSH 1
|
|
|
--#define TCIOFLUSH 2
|
|
|
--
|
|
|
--#define TCSANOW 0
|
|
|
--#define TCSADRAIN 1
|
|
|
--#define TCSAFLUSH 2
|
|
|
--
|
|
|
--#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
--#define CBAUDEX 0010000
|
|
|
--#define CRTSCTS 020000000000
|
|
|
--#define EXTPROC 0200000
|
|
|
--#define XTABS 0014000
|
|
|
--#endif
|
|
|
---- a/arch/x86_64/pthread_arch.h
|
|
|
-+++ b/arch/x86_64/pthread_arch.h
|
|
|
-@@ -7,4 +7,4 @@ static inline struct pthread *__pthread_
|
|
|
-
|
|
|
- #define TP_ADJ(p) (p)
|
|
|
-
|
|
|
--#define CANCEL_REG_IP 16
|
|
|
-+#define MC_PC gregs[REG_RIP]
|
|
|
---- a/configure
|
|
|
-+++ b/configure
|
|
|
-@@ -9,6 +9,9 @@ VAR=VALUE. See below for descriptions o
|
|
|
-
|
|
|
- Defaults for the options are specified in brackets.
|
|
|
-
|
|
|
-+Configuration:
|
|
|
-+ --srcdir=DIR source directory [detected]
|
|
|
-+
|
|
|
- Installation directories:
|
|
|
- --prefix=PREFIX main installation prefix [/usr/local/musl]
|
|
|
- --exec-prefix=EPREFIX installation prefix for executable files [PREFIX]
|
|
|
-@@ -117,6 +120,7 @@ CFLAGS_TRY=
|
|
|
- LDFLAGS_AUTO=
|
|
|
- LDFLAGS_TRY=
|
|
|
- OPTIMIZE_GLOBS=
|
|
|
-+srcdir=
|
|
|
- prefix=/usr/local/musl
|
|
|
- exec_prefix='$(prefix)'
|
|
|
- bindir='$(exec_prefix)/bin'
|
|
|
-@@ -139,6 +143,7 @@ clang_wrapper=no
|
|
|
- for arg ; do
|
|
|
- case "$arg" in
|
|
|
- --help) usage ;;
|
|
|
-+--srcdir=*) srcdir=${arg#*=} ;;
|
|
|
- --prefix=*) prefix=${arg#*=} ;;
|
|
|
- --exec-prefix=*) exec_prefix=${arg#*=} ;;
|
|
|
- --bindir=*) bindir=${arg#*=} ;;
|
|
|
-@@ -179,11 +184,23 @@ LIBCC=*) LIBCC=${arg#*=} ;;
|
|
|
- esac
|
|
|
- done
|
|
|
-
|
|
|
--for i in prefix exec_prefix bindir libdir includedir syslibdir ; do
|
|
|
-+for i in srcdir prefix exec_prefix bindir libdir includedir syslibdir ; do
|
|
|
- stripdir $i
|
|
|
- done
|
|
|
-
|
|
|
- #
|
|
|
-+# Get the source dir for out-of-tree builds
|
|
|
-+#
|
|
|
-+if test -z "$srcdir" ; then
|
|
|
-+srcdir="${0%/configure}"
|
|
|
-+stripdir srcdir
|
|
|
-+fi
|
|
|
-+abs_builddir="$(pwd)" || fail "$0: cannot determine working directory"
|
|
|
-+abs_srcdir="$(cd $srcdir && pwd)" || fail "$0: invalid source directory $srcdir"
|
|
|
-+test "$abs_srcdir" = "$abs_builddir" && srcdir=.
|
|
|
-+test "$srcdir" != "." -a -f Makefile -a ! -h Makefile && fail "$0: Makefile already exists in the working directory"
|
|
|
-+
|
|
|
-+#
|
|
|
- # Get a temp filename we can use
|
|
|
- #
|
|
|
- i=0
|
|
|
-@@ -263,11 +280,11 @@ fi
|
|
|
- fi
|
|
|
-
|
|
|
- if test "$gcc_wrapper" = yes ; then
|
|
|
--tools="$tools tools/musl-gcc"
|
|
|
-+tools="$tools obj/musl-gcc"
|
|
|
- tool_libs="$tool_libs lib/musl-gcc.specs"
|
|
|
- fi
|
|
|
- if test "$clang_wrapper" = yes ; then
|
|
|
--tools="$tools tools/musl-clang tools/ld.musl-clang"
|
|
|
-+tools="$tools obj/musl-clang obj/ld.musl-clang"
|
|
|
- fi
|
|
|
-
|
|
|
- #
|
|
|
-@@ -321,7 +338,7 @@ __attribute__((__may_alias__))
|
|
|
- #endif
|
|
|
- x;
|
|
|
- EOF
|
|
|
--if $CC $CFLAGS_C99FSE -I./arch/$ARCH -I./include $CPPFLAGS $CFLAGS \
|
|
|
-+if $CC $CFLAGS_C99FSE $CPPFLAGS $CFLAGS \
|
|
|
- -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
|
|
|
- printf "no\n"
|
|
|
- else
|
|
|
-@@ -330,6 +347,13 @@ CFLAGS_C99FSE="$CFLAGS_C99FSE -D__may_al
|
|
|
- fi
|
|
|
-
|
|
|
- #
|
|
|
-+# The GNU toolchain defaults to assuming unmarked files need an
|
|
|
-+# executable stack, potentially exposing vulnerabilities in programs
|
|
|
-+# linked with such object files. Fix this.
|
|
|
-+#
|
|
|
-+tryflag CFLAGS_C99FSE -Wa,--noexecstack
|
|
|
-+
|
|
|
-+#
|
|
|
- # Check for options to disable stack protector, which needs to be
|
|
|
- # disabled for a few early-bootstrap translation units. If not found,
|
|
|
- # this is not an error; we assume the toolchain does not do ssp.
|
|
|
-@@ -430,11 +454,15 @@ tryflag CFLAGS_AUTO -fno-unwind-tables
|
|
|
- tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables
|
|
|
-
|
|
|
- #
|
|
|
--# The GNU toolchain defaults to assuming unmarked files need an
|
|
|
--# executable stack, potentially exposing vulnerabilities in programs
|
|
|
--# linked with such object files. Fix this.
|
|
|
-+# Attempt to put each function and each data object in its own
|
|
|
-+# section. This both allows additional size optimizations at link
|
|
|
-+# time and works around a dangerous class of compiler/assembler bugs
|
|
|
-+# whereby relative address expressions are constant-folded by the
|
|
|
-+# assembler even when one or more of the symbols involved is
|
|
|
-+# replaceable. See gas pr 18561 and gcc pr 66609, 68178, etc.
|
|
|
- #
|
|
|
--tryflag CFLAGS_AUTO -Wa,--noexecstack
|
|
|
-+tryflag CFLAGS_AUTO -ffunction-sections
|
|
|
-+tryflag CFLAGS_AUTO -fdata-sections
|
|
|
-
|
|
|
- #
|
|
|
- # On x86, make sure we don't have incompatible instruction set
|
|
|
-@@ -489,7 +517,7 @@ int foo(void) { }
|
|
|
- int bar(void) { fp = foo; return foo(); }
|
|
|
- EOF
|
|
|
- if $CC $CFLAGS_C99FSE $CPPFLAGS $CFLAGS \
|
|
|
-- -DSHARED -fPIC -I./src/internal -include vis.h \
|
|
|
-+ -DSHARED -fPIC -I$srcdir/src/internal -include vis.h \
|
|
|
- -nostdlib -shared -Wl,-Bsymbolic-functions \
|
|
|
- -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
|
|
|
- visibility=yes
|
|
|
-@@ -504,6 +532,25 @@ CFLAGS_AUTO="$CFLAGS_AUTO -include vis.h
|
|
|
- CFLAGS_AUTO="${CFLAGS_AUTO# }"
|
|
|
- fi
|
|
|
-
|
|
|
-+# Determine if the compiler produces position-independent code (PIC)
|
|
|
-+# by default. If so, we don't need to compile separate object files
|
|
|
-+# for libc.a and libc.so.
|
|
|
-+if trycppif __PIC__ "$CFLAGS_C99FSE $CPPFLAGS $CFLAGS" ; then
|
|
|
-+pic_default=yes
|
|
|
-+else
|
|
|
-+pic_default=no
|
|
|
-+fi
|
|
|
-+
|
|
|
-+# Reduce space lost to padding for alignment purposes by sorting data
|
|
|
-+# objects according to their alignment reqirements. This approximates
|
|
|
-+# optimal packing.
|
|
|
-+tryldflag LDFLAGS_AUTO -Wl,--sort-section,alignment
|
|
|
-+tryldflag LDFLAGS_AUTO -Wl,--sort-common
|
|
|
-+
|
|
|
-+# When linking shared library, drop dummy weak definitions that were
|
|
|
-+# replaced by strong definitions from other translation units.
|
|
|
-+tryldflag LDFLAGS_AUTO -Wl,--gc-sections
|
|
|
-+
|
|
|
- # Some patched GCC builds have these defaults messed up...
|
|
|
- tryldflag LDFLAGS_AUTO -Wl,--hash-style=both
|
|
|
-
|
|
|
-@@ -513,6 +560,11 @@ tryldflag LDFLAGS_AUTO -Wl,--hash-style=
|
|
|
- # runtime library; implementation error is also a possibility.
|
|
|
- tryldflag LDFLAGS_AUTO -Wl,--no-undefined
|
|
|
-
|
|
|
-+# Avoid exporting symbols from compiler runtime libraries. They
|
|
|
-+# should be hidden anyway, but some toolchains including old gcc
|
|
|
-+# versions built without shared library support and pcc are broken.
|
|
|
-+tryldflag LDFLAGS_AUTO -Wl,--exclude-libs=ALL
|
|
|
-+
|
|
|
- test "$shared" = "no" || {
|
|
|
- # Disable dynamic linking if ld is broken and can't do -Bsymbolic-functions
|
|
|
- LDFLAGS_DUMMY=
|
|
|
-@@ -599,8 +651,9 @@ echo '#include <float.h>' > "$tmpc"
|
|
|
- echo '#if LDBL_MANT_DIG == 53' >> "$tmpc"
|
|
|
- echo 'typedef char ldcheck[9-(int)sizeof(long double)];' >> "$tmpc"
|
|
|
- echo '#endif' >> "$tmpc"
|
|
|
--if $CC $CFLAGS_C99FSE -I./arch/$ARCH -I./include $CPPFLAGS $CFLAGS \
|
|
|
-- -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
|
|
|
-+if $CC $CFLAGS_C99FSE \
|
|
|
-+ -I$srcdir/arch/$ARCH -I$srcdir/arch/generic -I$srcdir/include \
|
|
|
-+ $CPPFLAGS $CFLAGS -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
|
|
|
- printf "yes\n"
|
|
|
- else
|
|
|
- printf "no\n"
|
|
|
-@@ -622,6 +675,7 @@ cat << EOF
|
|
|
- ARCH = $ARCH
|
|
|
- SUBARCH = $SUBARCH
|
|
|
- ASMSUBARCH = $ASMSUBARCH
|
|
|
-+srcdir = $srcdir
|
|
|
- prefix = $prefix
|
|
|
- exec_prefix = $exec_prefix
|
|
|
- bindir = $bindir
|
|
|
-@@ -629,12 +683,14 @@ libdir = $libdir
|
|
|
- includedir = $includedir
|
|
|
- syslibdir = $syslibdir
|
|
|
- CC = $CC
|
|
|
--CFLAGS = $CFLAGS_AUTO $CFLAGS
|
|
|
-+CFLAGS = $CFLAGS
|
|
|
-+CFLAGS_AUTO = $CFLAGS_AUTO
|
|
|
- CFLAGS_C99FSE = $CFLAGS_C99FSE
|
|
|
- CFLAGS_MEMOPS = $CFLAGS_MEMOPS
|
|
|
- CFLAGS_NOSSP = $CFLAGS_NOSSP
|
|
|
- CPPFLAGS = $CPPFLAGS
|
|
|
--LDFLAGS = $LDFLAGS_AUTO $LDFLAGS
|
|
|
-+LDFLAGS = $LDFLAGS
|
|
|
-+LDFLAGS_AUTO = $LDFLAGS_AUTO
|
|
|
- CROSS_COMPILE = $CROSS_COMPILE
|
|
|
- LIBCC = $LIBCC
|
|
|
- OPTIMIZE_GLOBS = $OPTIMIZE_GLOBS
|
|
|
-@@ -646,6 +702,9 @@ test "x$static" = xno && echo "STATIC_LI
|
|
|
- test "x$shared" = xno && echo "SHARED_LIBS ="
|
|
|
- test "x$cc_family" = xgcc && echo 'WRAPCC_GCC = $(CC)'
|
|
|
- test "x$cc_family" = xclang && echo 'WRAPCC_CLANG = $(CC)'
|
|
|
-+test "x$pic_default" = xyes && echo 'AOBJS = $(LOBJS)'
|
|
|
- exec 1>&3 3>&-
|
|
|
-
|
|
|
-+test "$srcdir" = "." || ln -sf $srcdir/Makefile .
|
|
|
-+
|
|
|
- printf "done\n"
|
|
|
---- a/crt/arm/crti.s
|
|
|
-+++ b/crt/arm/crti.s
|
|
|
-@@ -1,3 +1,5 @@
|
|
|
-+.syntax unified
|
|
|
-+
|
|
|
- .section .init
|
|
|
- .global _init
|
|
|
- .type _init,%function
|
|
|
---- a/crt/arm/crtn.s
|
|
|
-+++ b/crt/arm/crtn.s
|
|
|
-@@ -1,11 +1,9 @@
|
|
|
-+.syntax unified
|
|
|
-+
|
|
|
- .section .init
|
|
|
- pop {r0,lr}
|
|
|
-- tst lr,#1
|
|
|
-- moveq pc,lr
|
|
|
- bx lr
|
|
|
-
|
|
|
- .section .fini
|
|
|
- pop {r0,lr}
|
|
|
-- tst lr,#1
|
|
|
-- moveq pc,lr
|
|
|
- bx lr
|
|
|
---- a/crt/rcrt1.c
|
|
|
-+++ b/crt/rcrt1.c
|
|
|
-@@ -1,7 +1,7 @@
|
|
|
- #define SHARED
|
|
|
- #define START "_start"
|
|
|
- #define _dlstart_c _start_c
|
|
|
--#include "../src/ldso/dlstart.c"
|
|
|
-+#include "../ldso/dlstart.c"
|
|
|
-
|
|
|
- int main();
|
|
|
- void _init() __attribute__((weak));
|
|
|
---- a/include/complex.h
|
|
|
-+++ b/include/complex.h
|
|
|
-@@ -116,7 +116,7 @@ long double creall(long double complex);
|
|
|
-
|
|
|
- #if __STDC_VERSION__ >= 201112L
|
|
|
- #if defined(_Imaginary_I)
|
|
|
--#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y)))
|
|
|
-+#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y))
|
|
|
- #elif defined(__clang__)
|
|
|
- #define __CMPLX(x, y, t) (+(_Complex t){ (t)(x), (t)(y) })
|
|
|
- #else
|
|
|
---- a/include/netinet/in.h
|
|
|
-+++ b/include/netinet/in.h
|
|
|
-@@ -103,6 +103,7 @@ uint16_t ntohs(uint16_t);
|
|
|
- #define IPPROTO_SCTP 132
|
|
|
- #define IPPROTO_MH 135
|
|
|
- #define IPPROTO_UDPLITE 136
|
|
|
-+#define IPPROTO_MPLS 137
|
|
|
- #define IPPROTO_RAW 255
|
|
|
- #define IPPROTO_MAX 256
|
|
|
-
|
|
|
-@@ -200,6 +201,7 @@ uint16_t ntohs(uint16_t);
|
|
|
- #define IP_MINTTL 21
|
|
|
- #define IP_NODEFRAG 22
|
|
|
- #define IP_CHECKSUM 23
|
|
|
-+#define IP_BIND_ADDRESS_NO_PORT 24
|
|
|
- #define IP_MULTICAST_IF 32
|
|
|
- #define IP_MULTICAST_TTL 33
|
|
|
- #define IP_MULTICAST_LOOP 34
|
|
|
---- a/include/netinet/tcp.h
|
|
|
-+++ b/include/netinet/tcp.h
|
|
|
-@@ -27,6 +27,9 @@
|
|
|
- #define TCP_FASTOPEN 23
|
|
|
- #define TCP_TIMESTAMP 24
|
|
|
- #define TCP_NOTSENT_LOWAT 25
|
|
|
-+#define TCP_CC_INFO 26
|
|
|
-+#define TCP_SAVE_SYN 27
|
|
|
-+#define TCP_SAVED_SYN 28
|
|
|
-
|
|
|
- #define TCP_ESTABLISHED 1
|
|
|
- #define TCP_SYN_SENT 2
|
|
|
-@@ -41,7 +44,20 @@
|
|
|
- #define TCP_CLOSING 11
|
|
|
-
|
|
|
- #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
-+#define TCPOPT_EOL 0
|
|
|
-+#define TCPOPT_NOP 1
|
|
|
-+#define TCPOPT_MAXSEG 2
|
|
|
-+#define TCPOPT_WINDOW 3
|
|
|
-+#define TCPOPT_SACK_PERMITTED 4
|
|
|
-+#define TCPOPT_SACK 5
|
|
|
-+#define TCPOPT_TIMESTAMP 8
|
|
|
-+#define TCPOLEN_SACK_PERMITTED 2
|
|
|
-+#define TCPOLEN_WINDOW 3
|
|
|
-+#define TCPOLEN_MAXSEG 4
|
|
|
-+#define TCPOLEN_TIMESTAMP 10
|
|
|
-+
|
|
|
- #define SOL_TCP 6
|
|
|
-+
|
|
|
- #include <sys/types.h>
|
|
|
- #include <sys/socket.h>
|
|
|
- #include <stdint.h>
|
|
|
-@@ -164,6 +180,10 @@ struct tcp_info
|
|
|
- uint32_t tcpi_total_retrans;
|
|
|
- uint64_t tcpi_pacing_rate;
|
|
|
- uint64_t tcpi_max_pacing_rate;
|
|
|
-+ uint64_t tcpi_bytes_acked;
|
|
|
-+ uint64_t tcpi_bytes_received;
|
|
|
-+ uint32_t tcpi_segs_out;
|
|
|
-+ uint32_t tcpi_segs_in;
|
|
|
- };
|
|
|
-
|
|
|
- #define TCP_MD5SIG_MAXKEYLEN 80
|
|
|
---- a/include/netpacket/packet.h
|
|
|
-+++ b/include/netpacket/packet.h
|
|
|
-@@ -32,10 +32,27 @@ struct packet_mreq {
|
|
|
- #define PACKET_RECV_OUTPUT 3
|
|
|
- #define PACKET_RX_RING 5
|
|
|
- #define PACKET_STATISTICS 6
|
|
|
-+#define PACKET_COPY_THRESH 7
|
|
|
-+#define PACKET_AUXDATA 8
|
|
|
-+#define PACKET_ORIGDEV 9
|
|
|
-+#define PACKET_VERSION 10
|
|
|
-+#define PACKET_HDRLEN 11
|
|
|
-+#define PACKET_RESERVE 12
|
|
|
-+#define PACKET_TX_RING 13
|
|
|
-+#define PACKET_LOSS 14
|
|
|
-+#define PACKET_VNET_HDR 15
|
|
|
-+#define PACKET_TX_TIMESTAMP 16
|
|
|
-+#define PACKET_TIMESTAMP 17
|
|
|
-+#define PACKET_FANOUT 18
|
|
|
-+#define PACKET_TX_HAS_OFF 19
|
|
|
-+#define PACKET_QDISC_BYPASS 20
|
|
|
-+#define PACKET_ROLLOVER_STATS 21
|
|
|
-+#define PACKET_FANOUT_DATA 22
|
|
|
-
|
|
|
- #define PACKET_MR_MULTICAST 0
|
|
|
- #define PACKET_MR_PROMISC 1
|
|
|
- #define PACKET_MR_ALLMULTI 2
|
|
|
-+#define PACKET_MR_UNICAST 3
|
|
|
-
|
|
|
- #ifdef __cplusplus
|
|
|
- }
|
|
|
---- a/include/signal.h
|
|
|
-+++ b/include/signal.h
|
|
|
-@@ -27,8 +27,6 @@ extern "C" {
|
|
|
-
|
|
|
- #include <bits/alltypes.h>
|
|
|
-
|
|
|
--#define SIG_HOLD ((void (*)(int)) 2)
|
|
|
--
|
|
|
- #define SIG_BLOCK 0
|
|
|
- #define SIG_UNBLOCK 1
|
|
|
- #define SIG_SETMASK 2
|
|
|
-@@ -43,6 +41,18 @@ extern "C" {
|
|
|
- #define SI_USER 0
|
|
|
- #define SI_KERNEL 128
|
|
|
-
|
|
|
-+typedef struct sigaltstack stack_t;
|
|
|
-+
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#include <bits/signal.h>
|
|
|
-+
|
|
|
-+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|
|
|
-+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
|
|
|
-+ || defined(_BSD_SOURCE)
|
|
|
-+
|
|
|
-+#define SIG_HOLD ((void (*)(int)) 2)
|
|
|
-+
|
|
|
- #define FPE_INTDIV 1
|
|
|
- #define FPE_INTOVF 2
|
|
|
- #define FPE_FLTDIV 3
|
|
|
-@@ -78,15 +88,17 @@ extern "C" {
|
|
|
- #define CLD_STOPPED 5
|
|
|
- #define CLD_CONTINUED 6
|
|
|
-
|
|
|
--typedef struct sigaltstack stack_t;
|
|
|
--
|
|
|
- union sigval {
|
|
|
- int sival_int;
|
|
|
- void *sival_ptr;
|
|
|
- };
|
|
|
-
|
|
|
- typedef struct {
|
|
|
-+#ifdef __SI_SWAP_ERRNO_CODE
|
|
|
-+ int si_signo, si_code, si_errno;
|
|
|
-+#else
|
|
|
- int si_signo, si_errno, si_code;
|
|
|
-+#endif
|
|
|
- union {
|
|
|
- char __pad[128 - 2*sizeof(int) - sizeof(long)];
|
|
|
- struct {
|
|
|
-@@ -240,8 +252,6 @@ int sigandset(sigset_t *, const sigset_t
|
|
|
- #define SA_ONESHOT SA_RESETHAND
|
|
|
- #endif
|
|
|
-
|
|
|
--#include <bits/signal.h>
|
|
|
--
|
|
|
- #define SIG_ERR ((void (*)(int))-1)
|
|
|
- #define SIG_DFL ((void (*)(int)) 0)
|
|
|
- #define SIG_IGN ((void (*)(int)) 1)
|
|
|
---- a/include/sys/mman.h
|
|
|
-+++ b/include/sys/mman.h
|
|
|
-@@ -39,6 +39,7 @@ int remap_file_pages (void *, size_t, in
|
|
|
- #endif
|
|
|
-
|
|
|
- #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
|
|
-+#define MLOCK_ONFAULT 0x01
|
|
|
- int madvise (void *, size_t, int);
|
|
|
- int mincore (void *, size_t, unsigned char *);
|
|
|
- #endif
|
|
|
---- a/include/sys/mount.h
|
|
|
-+++ b/include/sys/mount.h
|
|
|
-@@ -46,12 +46,13 @@ extern "C" {
|
|
|
- #define MS_KERNMOUNT (1<<22)
|
|
|
- #define MS_I_VERSION (1<<23)
|
|
|
- #define MS_STRICTATIME (1<<24)
|
|
|
-+#define MS_LAZYTIME (1<<25)
|
|
|
- #define MS_NOSEC (1<<28)
|
|
|
- #define MS_BORN (1<<29)
|
|
|
- #define MS_ACTIVE (1<<30)
|
|
|
- #define MS_NOUSER (1U<<31)
|
|
|
-
|
|
|
--#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION)
|
|
|
-+#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|MS_LAZYTIME)
|
|
|
-
|
|
|
- #define MS_MGC_VAL 0xc0ed0000
|
|
|
- #define MS_MGC_MSK 0xffff0000
|
|
|
---- a/include/sys/prctl.h
|
|
|
-+++ b/include/sys/prctl.h
|
|
|
-@@ -124,6 +124,12 @@ struct prctl_mm_map {
|
|
|
- #define PR_FP_MODE_FR (1 << 0)
|
|
|
- #define PR_FP_MODE_FRE (1 << 1)
|
|
|
-
|
|
|
-+#define PR_CAP_AMBIENT 47
|
|
|
-+#define PR_CAP_AMBIENT_IS_SET 1
|
|
|
-+#define PR_CAP_AMBIENT_RAISE 2
|
|
|
-+#define PR_CAP_AMBIENT_LOWER 3
|
|
|
-+#define PR_CAP_AMBIENT_CLEAR_ALL 4
|
|
|
-+
|
|
|
- int prctl (int, ...);
|
|
|
-
|
|
|
- #ifdef __cplusplus
|
|
|
---- a/include/sys/ptrace.h
|
|
|
-+++ b/include/sys/ptrace.h
|
|
|
-@@ -39,6 +39,7 @@ extern "C" {
|
|
|
- #define PTRACE_PEEKSIGINFO 0x4209
|
|
|
- #define PTRACE_GETSIGMASK 0x420a
|
|
|
- #define PTRACE_SETSIGMASK 0x420b
|
|
|
-+#define PTRACE_SECCOMP_GET_FILTER 0x420c
|
|
|
-
|
|
|
- #define PT_READ_I PTRACE_PEEKTEXT
|
|
|
- #define PT_READ_D PTRACE_PEEKDATA
|
|
|
-@@ -72,7 +73,8 @@ extern "C" {
|
|
|
- #define PTRACE_O_TRACEEXIT 0x00000040
|
|
|
- #define PTRACE_O_TRACESECCOMP 0x00000080
|
|
|
- #define PTRACE_O_EXITKILL 0x00100000
|
|
|
--#define PTRACE_O_MASK 0x001000ff
|
|
|
-+#define PTRACE_O_SUSPEND_SECCOMP 0x00200000
|
|
|
-+#define PTRACE_O_MASK 0x003000ff
|
|
|
-
|
|
|
- #define PTRACE_EVENT_FORK 1
|
|
|
- #define PTRACE_EVENT_VFORK 2
|
|
|
---- a/include/sys/socket.h
|
|
|
-+++ b/include/sys/socket.h
|
|
|
-@@ -96,6 +96,7 @@ struct linger
|
|
|
- #define PF_WANPIPE 25
|
|
|
- #define PF_LLC 26
|
|
|
- #define PF_IB 27
|
|
|
-+#define PF_MPLS 28
|
|
|
- #define PF_CAN 29
|
|
|
- #define PF_TIPC 30
|
|
|
- #define PF_BLUETOOTH 31
|
|
|
-@@ -141,6 +142,7 @@ struct linger
|
|
|
- #define AF_WANPIPE PF_WANPIPE
|
|
|
- #define AF_LLC PF_LLC
|
|
|
- #define AF_IB PF_IB
|
|
|
-+#define AF_MPLS PF_MPLS
|
|
|
- #define AF_CAN PF_CAN
|
|
|
- #define AF_TIPC PF_TIPC
|
|
|
- #define AF_BLUETOOTH PF_BLUETOOTH
|
|
|
-@@ -255,6 +257,7 @@ struct linger
|
|
|
- #define MSG_NOSIGNAL 0x4000
|
|
|
- #define MSG_MORE 0x8000
|
|
|
- #define MSG_WAITFORONE 0x10000
|
|
|
-+#define MSG_FASTOPEN 0x20000000
|
|
|
- #define MSG_CMSG_CLOEXEC 0x40000000
|
|
|
-
|
|
|
- #define __CMSG_LEN(cmsg) (((cmsg)->cmsg_len + sizeof(long) - 1) & ~(long)(sizeof(long) - 1))
|
|
|
---- /dev/null
|
|
|
-+++ b/ldso/dlstart.c
|
|
|
-@@ -0,0 +1,146 @@
|
|
|
-+#include <stddef.h>
|
|
|
-+#include "dynlink.h"
|
|
|
-+
|
|
|
-+#ifndef START
|
|
|
-+#define START "_dlstart"
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#include "crt_arch.h"
|
|
|
-+
|
|
|
-+#ifndef GETFUNCSYM
|
|
|
-+#define GETFUNCSYM(fp, sym, got) do { \
|
|
|
-+ __attribute__((__visibility__("hidden"))) void sym(); \
|
|
|
-+ static void (*static_func_ptr)() = sym; \
|
|
|
-+ __asm__ __volatile__ ( "" : "+m"(static_func_ptr) : : "memory"); \
|
|
|
-+ *(fp) = static_func_ptr; } while(0)
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+void _dlstart_c(size_t *sp, size_t *dynv)
|
|
|
-+{
|
|
|
-+ size_t i, aux[AUX_CNT], dyn[DYN_CNT];
|
|
|
-+ size_t *rel, rel_size, base;
|
|
|
-+
|
|
|
-+ int argc = *sp;
|
|
|
-+ char **argv = (void *)(sp+1);
|
|
|
-+
|
|
|
-+ for (i=argc+1; argv[i]; i++);
|
|
|
-+ size_t *auxv = (void *)(argv+i+1);
|
|
|
-+
|
|
|
-+ for (i=0; i<AUX_CNT; i++) aux[i] = 0;
|
|
|
-+ for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT)
|
|
|
-+ aux[auxv[i]] = auxv[i+1];
|
|
|
-+
|
|
|
-+#if DL_FDPIC
|
|
|
-+ struct fdpic_loadseg *segs, fakeseg;
|
|
|
-+ size_t j;
|
|
|
-+ if (dynv) {
|
|
|
-+ /* crt_arch.h entry point asm is responsible for reserving
|
|
|
-+ * space and moving the extra fdpic arguments to the stack
|
|
|
-+ * vector where they are easily accessible from C. */
|
|
|
-+ segs = ((struct fdpic_loadmap *)(sp[-1] ? sp[-1] : sp[-2]))->segs;
|
|
|
-+ } else {
|
|
|
-+ /* If dynv is null, the entry point was started from loader
|
|
|
-+ * that is not fdpic-aware. We can assume normal fixed-
|
|
|
-+ * displacement ELF loading was performed, but when ldso was
|
|
|
-+ * run as a command, finding the Ehdr is a heursitic: we
|
|
|
-+ * have to assume Phdrs start in the first 4k of the file. */
|
|
|
-+ base = aux[AT_BASE];
|
|
|
-+ if (!base) base = aux[AT_PHDR] & -4096;
|
|
|
-+ segs = &fakeseg;
|
|
|
-+ segs[0].addr = base;
|
|
|
-+ segs[0].p_vaddr = 0;
|
|
|
-+ segs[0].p_memsz = -1;
|
|
|
-+ Ehdr *eh = (void *)base;
|
|
|
-+ Phdr *ph = (void *)(base + eh->e_phoff);
|
|
|
-+ size_t phnum = eh->e_phnum;
|
|
|
-+ size_t phent = eh->e_phentsize;
|
|
|
-+ while (phnum-- && ph->p_type != PT_DYNAMIC)
|
|
|
-+ ph = (void *)((size_t)ph + phent);
|
|
|
-+ dynv = (void *)(base + ph->p_vaddr);
|
|
|
-+ }
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+ for (i=0; i<DYN_CNT; i++) dyn[i] = 0;
|
|
|
-+ for (i=0; dynv[i]; i+=2) if (dynv[i]<DYN_CNT)
|
|
|
-+ dyn[dynv[i]] = dynv[i+1];
|
|
|
-+
|
|
|
-+#if DL_FDPIC
|
|
|
-+ for (i=0; i<DYN_CNT; i++) {
|
|
|
-+ if (i==DT_RELASZ || i==DT_RELSZ) continue;
|
|
|
-+ if (!dyn[i]) continue;
|
|
|
-+ for (j=0; dyn[i]-segs[j].p_vaddr >= segs[j].p_memsz; j++);
|
|
|
-+ dyn[i] += segs[j].addr - segs[j].p_vaddr;
|
|
|
-+ }
|
|
|
-+ base = 0;
|
|
|
-+
|
|
|
-+ const Sym *syms = (void *)dyn[DT_SYMTAB];
|
|
|
-+
|
|
|
-+ rel = (void *)dyn[DT_RELA];
|
|
|
-+ rel_size = dyn[DT_RELASZ];
|
|
|
-+ for (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) {
|
|
|
-+ if (!IS_RELATIVE(rel[1], syms)) continue;
|
|
|
-+ for (j=0; rel[0]-segs[j].p_vaddr >= segs[j].p_memsz; j++);
|
|
|
-+ size_t *rel_addr = (void *)
|
|
|
-+ (rel[0] + segs[j].addr - segs[j].p_vaddr);
|
|
|
-+ if (R_TYPE(rel[1]) == REL_FUNCDESC_VAL) {
|
|
|
-+ *rel_addr += segs[rel_addr[1]].addr
|
|
|
-+ - segs[rel_addr[1]].p_vaddr
|
|
|
-+ + syms[R_SYM(rel[1])].st_value;
|
|
|
-+ rel_addr[1] = dyn[DT_PLTGOT];
|
|
|
-+ } else {
|
|
|
-+ size_t val = syms[R_SYM(rel[1])].st_value;
|
|
|
-+ for (j=0; val-segs[j].p_vaddr >= segs[j].p_memsz; j++);
|
|
|
-+ *rel_addr = rel[2] + segs[j].addr - segs[j].p_vaddr + val;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+#else
|
|
|
-+ /* If the dynamic linker is invoked as a command, its load
|
|
|
-+ * address is not available in the aux vector. Instead, compute
|
|
|
-+ * the load address as the difference between &_DYNAMIC and the
|
|
|
-+ * virtual address in the PT_DYNAMIC program header. */
|
|
|
-+ base = aux[AT_BASE];
|
|
|
-+ if (!base) {
|
|
|
-+ size_t phnum = aux[AT_PHNUM];
|
|
|
-+ size_t phentsize = aux[AT_PHENT];
|
|
|
-+ Phdr *ph = (void *)aux[AT_PHDR];
|
|
|
-+ for (i=phnum; i--; ph = (void *)((char *)ph + phentsize)) {
|
|
|
-+ if (ph->p_type == PT_DYNAMIC) {
|
|
|
-+ base = (size_t)dynv - ph->p_vaddr;
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* MIPS uses an ugly packed form for GOT relocations. Since we
|
|
|
-+ * can't make function calls yet and the code is tiny anyway,
|
|
|
-+ * it's simply inlined here. */
|
|
|
-+ if (NEED_MIPS_GOT_RELOCS) {
|
|
|
-+ size_t local_cnt = 0;
|
|
|
-+ size_t *got = (void *)(base + dyn[DT_PLTGOT]);
|
|
|
-+ for (i=0; dynv[i]; i+=2) if (dynv[i]==DT_MIPS_LOCAL_GOTNO)
|
|
|
-+ local_cnt = dynv[i+1];
|
|
|
-+ for (i=0; i<local_cnt; i++) got[i] += base;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ rel = (void *)(base+dyn[DT_REL]);
|
|
|
-+ rel_size = dyn[DT_RELSZ];
|
|
|
-+ for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t)) {
|
|
|
-+ if (!IS_RELATIVE(rel[1], 0)) continue;
|
|
|
-+ size_t *rel_addr = (void *)(base + rel[0]);
|
|
|
-+ *rel_addr += base;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ rel = (void *)(base+dyn[DT_RELA]);
|
|
|
-+ rel_size = dyn[DT_RELASZ];
|
|
|
-+ for (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) {
|
|
|
-+ if (!IS_RELATIVE(rel[1], 0)) continue;
|
|
|
-+ size_t *rel_addr = (void *)(base + rel[0]);
|
|
|
-+ *rel_addr = base + rel[2];
|
|
|
-+ }
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+ stage2_func dls2;
|
|
|
-+ GETFUNCSYM(&dls2, __dls2, base+dyn[DT_PLTGOT]);
|
|
|
-+ dls2((void *)base, sp);
|
|
|
-+}
|
|
|
---- /dev/null
|
|
|
-+++ b/ldso/dynlink.c
|
|
|
-@@ -0,0 +1,1931 @@
|
|
|
-+#define _GNU_SOURCE
|
|
|
-+#include <stdio.h>
|
|
|
-+#include <stdlib.h>
|
|
|
-+#include <stdarg.h>
|
|
|
-+#include <stddef.h>
|
|
|
-+#include <string.h>
|
|
|
-+#include <unistd.h>
|
|
|
-+#include <stdint.h>
|
|
|
-+#include <elf.h>
|
|
|
-+#include <sys/mman.h>
|
|
|
-+#include <limits.h>
|
|
|
-+#include <fcntl.h>
|
|
|
-+#include <sys/stat.h>
|
|
|
-+#include <errno.h>
|
|
|
-+#include <link.h>
|
|
|
-+#include <setjmp.h>
|
|
|
-+#include <pthread.h>
|
|
|
-+#include <ctype.h>
|
|
|
-+#include <dlfcn.h>
|
|
|
-+#include "pthread_impl.h"
|
|
|
-+#include "libc.h"
|
|
|
-+#include "dynlink.h"
|
|
|
-+
|
|
|
-+static void error(const char *, ...);
|
|
|
-+
|
|
|
-+#define MAXP2(a,b) (-(-(a)&-(b)))
|
|
|
-+#define ALIGN(x,y) ((x)+(y)-1 & -(y))
|
|
|
-+
|
|
|
-+struct debug {
|
|
|
-+ int ver;
|
|
|
-+ void *head;
|
|
|
-+ void (*bp)(void);
|
|
|
-+ int state;
|
|
|
-+ void *base;
|
|
|
-+};
|
|
|
-+
|
|
|
-+struct td_index {
|
|
|
-+ size_t args[2];
|
|
|
-+ struct td_index *next;
|
|
|
-+};
|
|
|
-+
|
|
|
-+struct dso {
|
|
|
-+#if DL_FDPIC
|
|
|
-+ struct fdpic_loadmap *loadmap;
|
|
|
-+#else
|
|
|
-+ unsigned char *base;
|
|
|
-+#endif
|
|
|
-+ char *name;
|
|
|
-+ size_t *dynv;
|
|
|
-+ struct dso *next, *prev;
|
|
|
-+
|
|
|
-+ Phdr *phdr;
|
|
|
-+ int phnum;
|
|
|
-+ size_t phentsize;
|
|
|
-+ int refcnt;
|
|
|
-+ Sym *syms;
|
|
|
-+ uint32_t *hashtab;
|
|
|
-+ uint32_t *ghashtab;
|
|
|
-+ int16_t *versym;
|
|
|
-+ char *strings;
|
|
|
-+ unsigned char *map;
|
|
|
-+ size_t map_len;
|
|
|
-+ dev_t dev;
|
|
|
-+ ino_t ino;
|
|
|
-+ signed char global;
|
|
|
-+ char relocated;
|
|
|
-+ char constructed;
|
|
|
-+ char kernel_mapped;
|
|
|
-+ struct dso **deps, *needed_by;
|
|
|
-+ char *rpath_orig, *rpath;
|
|
|
-+ struct tls_module tls;
|
|
|
-+ size_t tls_id;
|
|
|
-+ size_t relro_start, relro_end;
|
|
|
-+ void **new_dtv;
|
|
|
-+ unsigned char *new_tls;
|
|
|
-+ volatile int new_dtv_idx, new_tls_idx;
|
|
|
-+ struct td_index *td_index;
|
|
|
-+ struct dso *fini_next;
|
|
|
-+ char *shortname;
|
|
|
-+#if DL_FDPIC
|
|
|
-+ unsigned char *base;
|
|
|
-+#else
|
|
|
-+ struct fdpic_loadmap *loadmap;
|
|
|
-+#endif
|
|
|
-+ struct funcdesc {
|
|
|
-+ void *addr;
|
|
|
-+ size_t *got;
|
|
|
-+ } *funcdescs;
|
|
|
-+ size_t *got;
|
|
|
-+ char buf[];
|
|
|
-+};
|
|
|
-+
|
|
|
-+struct symdef {
|
|
|
-+ Sym *sym;
|
|
|
-+ struct dso *dso;
|
|
|
-+};
|
|
|
-+
|
|
|
-+int __init_tp(void *);
|
|
|
-+void __init_libc(char **, char *);
|
|
|
-+void *__copy_tls(unsigned char *);
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+const char *__libc_get_version(void);
|
|
|
-+
|
|
|
-+static struct builtin_tls {
|
|
|
-+ char c;
|
|
|
-+ struct pthread pt;
|
|
|
-+ void *space[16];
|
|
|
-+} builtin_tls[1];
|
|
|
-+#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
|
|
|
-+
|
|
|
-+#define ADDEND_LIMIT 4096
|
|
|
-+static size_t *saved_addends, *apply_addends_to;
|
|
|
-+
|
|
|
-+static struct dso ldso;
|
|
|
-+static struct dso *head, *tail, *fini_head;
|
|
|
-+static char *env_path, *sys_path;
|
|
|
-+static unsigned long long gencnt;
|
|
|
-+static int runtime;
|
|
|
-+static int ldd_mode;
|
|
|
-+static int ldso_fail;
|
|
|
-+static int noload;
|
|
|
-+static jmp_buf *rtld_fail;
|
|
|
-+static pthread_rwlock_t lock;
|
|
|
-+static struct debug debug;
|
|
|
-+static struct tls_module *tls_tail;
|
|
|
-+static size_t tls_cnt, tls_offset, tls_align = MIN_TLS_ALIGN;
|
|
|
-+static size_t static_tls_cnt;
|
|
|
-+static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE };
|
|
|
-+static struct fdpic_loadmap *app_loadmap;
|
|
|
-+static struct fdpic_dummy_loadmap app_dummy_loadmap;
|
|
|
-+
|
|
|
-+struct debug *_dl_debug_addr = &debug;
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0;
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+extern void (*const __init_array_end)(void), (*const __fini_array_end)(void);
|
|
|
-+
|
|
|
-+weak_alias(__init_array_start, __init_array_end);
|
|
|
-+weak_alias(__fini_array_start, __fini_array_end);
|
|
|
-+
|
|
|
-+static int dl_strcmp(const char *l, const char *r)
|
|
|
-+{
|
|
|
-+ for (; *l==*r && *l; l++, r++);
|
|
|
-+ return *(unsigned char *)l - *(unsigned char *)r;
|
|
|
-+}
|
|
|
-+#define strcmp(l,r) dl_strcmp(l,r)
|
|
|
-+
|
|
|
-+/* Compute load address for a virtual address in a given dso. */
|
|
|
-+#if DL_FDPIC
|
|
|
-+static void *laddr(const struct dso *p, size_t v)
|
|
|
-+{
|
|
|
-+ size_t j=0;
|
|
|
-+ if (!p->loadmap) return p->base + v;
|
|
|
-+ for (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz; j++);
|
|
|
-+ return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr);
|
|
|
-+}
|
|
|
-+#define fpaddr(p, v) ((void (*)())&(struct funcdesc){ \
|
|
|
-+ laddr(p, v), (p)->got })
|
|
|
-+#else
|
|
|
-+#define laddr(p, v) (void *)((p)->base + (v))
|
|
|
-+#define fpaddr(p, v) ((void (*)())laddr(p, v))
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+static void decode_vec(size_t *v, size_t *a, size_t cnt)
|
|
|
-+{
|
|
|
-+ size_t i;
|
|
|
-+ for (i=0; i<cnt; i++) a[i] = 0;
|
|
|
-+ for (; v[0]; v+=2) if (v[0]-1<cnt-1) {
|
|
|
-+ a[0] |= 1UL<<v[0];
|
|
|
-+ a[v[0]] = v[1];
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int search_vec(size_t *v, size_t *r, size_t key)
|
|
|
-+{
|
|
|
-+ for (; v[0]!=key; v+=2)
|
|
|
-+ if (!v[0]) return 0;
|
|
|
-+ *r = v[1];
|
|
|
-+ return 1;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static uint32_t sysv_hash(const char *s0)
|
|
|
-+{
|
|
|
-+ const unsigned char *s = (void *)s0;
|
|
|
-+ uint_fast32_t h = 0;
|
|
|
-+ while (*s) {
|
|
|
-+ h = 16*h + *s++;
|
|
|
-+ h ^= h>>24 & 0xf0;
|
|
|
-+ }
|
|
|
-+ return h & 0xfffffff;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static uint32_t gnu_hash(const char *s0)
|
|
|
-+{
|
|
|
-+ const unsigned char *s = (void *)s0;
|
|
|
-+ uint_fast32_t h = 5381;
|
|
|
-+ for (; *s; s++)
|
|
|
-+ h += h*32 + *s;
|
|
|
-+ return h;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso)
|
|
|
-+{
|
|
|
-+ size_t i;
|
|
|
-+ Sym *syms = dso->syms;
|
|
|
-+ uint32_t *hashtab = dso->hashtab;
|
|
|
-+ char *strings = dso->strings;
|
|
|
-+ for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) {
|
|
|
-+ if ((!dso->versym || dso->versym[i] >= 0)
|
|
|
-+ && (!strcmp(s, strings+syms[i].st_name)))
|
|
|
-+ return syms+i;
|
|
|
-+ }
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static Sym *gnu_lookup(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s)
|
|
|
-+{
|
|
|
-+ uint32_t nbuckets = hashtab[0];
|
|
|
-+ uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);
|
|
|
-+ uint32_t i = buckets[h1 % nbuckets];
|
|
|
-+
|
|
|
-+ if (!i) return 0;
|
|
|
-+
|
|
|
-+ uint32_t *hashval = buckets + nbuckets + (i - hashtab[1]);
|
|
|
-+
|
|
|
-+ for (h1 |= 1; ; i++) {
|
|
|
-+ uint32_t h2 = *hashval++;
|
|
|
-+ if ((h1 == (h2|1)) && (!dso->versym || dso->versym[i] >= 0)
|
|
|
-+ && !strcmp(s, dso->strings + dso->syms[i].st_name))
|
|
|
-+ return dso->syms+i;
|
|
|
-+ if (h2 & 1) break;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static Sym *gnu_lookup_filtered(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s, uint32_t fofs, size_t fmask)
|
|
|
-+{
|
|
|
-+ const size_t *bloomwords = (const void *)(hashtab+4);
|
|
|
-+ size_t f = bloomwords[fofs & (hashtab[2]-1)];
|
|
|
-+ if (!(f & fmask)) return 0;
|
|
|
-+
|
|
|
-+ f >>= (h1 >> hashtab[3]) % (8 * sizeof f);
|
|
|
-+ if (!(f & 1)) return 0;
|
|
|
-+
|
|
|
-+ return gnu_lookup(h1, hashtab, dso, s);
|
|
|
-+}
|
|
|
-+
|
|
|
-+#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
|
|
|
-+#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
|
|
|
-+
|
|
|
-+#ifndef ARCH_SYM_REJECT_UND
|
|
|
-+#define ARCH_SYM_REJECT_UND(s) 0
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
|
|
|
-+{
|
|
|
-+ uint32_t h = 0, gh, gho, *ght;
|
|
|
-+ size_t ghm = 0;
|
|
|
-+ struct symdef def = {0};
|
|
|
-+ for (; dso; dso=dso->next) {
|
|
|
-+ Sym *sym;
|
|
|
-+ if (!dso->global) continue;
|
|
|
-+ if ((ght = dso->ghashtab)) {
|
|
|
-+ if (!ghm) {
|
|
|
-+ gh = gnu_hash(s);
|
|
|
-+ int maskbits = 8 * sizeof ghm;
|
|
|
-+ gho = gh / maskbits;
|
|
|
-+ ghm = 1ul << gh % maskbits;
|
|
|
-+ }
|
|
|
-+ sym = gnu_lookup_filtered(gh, ght, dso, s, gho, ghm);
|
|
|
-+ } else {
|
|
|
-+ if (!h) h = sysv_hash(s);
|
|
|
-+ sym = sysv_lookup(s, h, dso);
|
|
|
-+ }
|
|
|
-+ if (!sym) continue;
|
|
|
-+ if (!sym->st_shndx)
|
|
|
-+ if (need_def || (sym->st_info&0xf) == STT_TLS
|
|
|
-+ || ARCH_SYM_REJECT_UND(sym))
|
|
|
-+ continue;
|
|
|
-+ if (!sym->st_value)
|
|
|
-+ if ((sym->st_info&0xf) != STT_TLS)
|
|
|
-+ continue;
|
|
|
-+ if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;
|
|
|
-+ if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;
|
|
|
-+
|
|
|
-+ if (def.sym && sym->st_info>>4 == STB_WEAK) continue;
|
|
|
-+ def.sym = sym;
|
|
|
-+ def.dso = dso;
|
|
|
-+ if (sym->st_info>>4 == STB_GLOBAL) break;
|
|
|
-+ }
|
|
|
-+ return def;
|
|
|
-+}
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic();
|
|
|
-+
|
|
|
-+static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)
|
|
|
-+{
|
|
|
-+ unsigned char *base = dso->base;
|
|
|
-+ Sym *syms = dso->syms;
|
|
|
-+ char *strings = dso->strings;
|
|
|
-+ Sym *sym;
|
|
|
-+ const char *name;
|
|
|
-+ void *ctx;
|
|
|
-+ int type;
|
|
|
-+ int sym_index;
|
|
|
-+ struct symdef def;
|
|
|
-+ size_t *reloc_addr;
|
|
|
-+ size_t sym_val;
|
|
|
-+ size_t tls_val;
|
|
|
-+ size_t addend;
|
|
|
-+ int skip_relative = 0, reuse_addends = 0, save_slot = 0;
|
|
|
-+
|
|
|
-+ if (dso == &ldso) {
|
|
|
-+ /* Only ldso's REL table needs addend saving/reuse. */
|
|
|
-+ if (rel == apply_addends_to)
|
|
|
-+ reuse_addends = 1;
|
|
|
-+ skip_relative = 1;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
|
|
|
-+ if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue;
|
|
|
-+ type = R_TYPE(rel[1]);
|
|
|
-+ if (type == REL_NONE) continue;
|
|
|
-+ sym_index = R_SYM(rel[1]);
|
|
|
-+ reloc_addr = laddr(dso, rel[0]);
|
|
|
-+ if (sym_index) {
|
|
|
-+ sym = syms + sym_index;
|
|
|
-+ name = strings + sym->st_name;
|
|
|
-+ ctx = type==REL_COPY ? head->next : head;
|
|
|
-+ def = (sym->st_info&0xf) == STT_SECTION
|
|
|
-+ ? (struct symdef){ .dso = dso, .sym = sym }
|
|
|
-+ : find_sym(ctx, name, type==REL_PLT);
|
|
|
-+ if (!def.sym && (sym->st_shndx != SHN_UNDEF
|
|
|
-+ || sym->st_info>>4 != STB_WEAK)) {
|
|
|
-+ error("Error relocating %s: %s: symbol not found",
|
|
|
-+ dso->name, name);
|
|
|
-+ if (runtime) longjmp(*rtld_fail, 1);
|
|
|
-+ continue;
|
|
|
-+ }
|
|
|
-+ } else {
|
|
|
-+ sym = 0;
|
|
|
-+ def.sym = 0;
|
|
|
-+ def.dso = dso;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ if (stride > 2) {
|
|
|
-+ addend = rel[2];
|
|
|
-+ } else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) {
|
|
|
-+ addend = 0;
|
|
|
-+ } else if (reuse_addends) {
|
|
|
-+ /* Save original addend in stage 2 where the dso
|
|
|
-+ * chain consists of just ldso; otherwise read back
|
|
|
-+ * saved addend since the inline one was clobbered. */
|
|
|
-+ if (head==&ldso)
|
|
|
-+ saved_addends[save_slot] = *reloc_addr;
|
|
|
-+ addend = saved_addends[save_slot++];
|
|
|
-+ } else {
|
|
|
-+ addend = *reloc_addr;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0;
|
|
|
-+ tls_val = def.sym ? def.sym->st_value : 0;
|
|
|
-+
|
|
|
-+ switch(type) {
|
|
|
-+ case REL_NONE:
|
|
|
-+ break;
|
|
|
-+ case REL_OFFSET:
|
|
|
-+ addend -= (size_t)reloc_addr;
|
|
|
-+ case REL_SYMBOLIC:
|
|
|
-+ case REL_GOT:
|
|
|
-+ case REL_PLT:
|
|
|
-+ *reloc_addr = sym_val + addend;
|
|
|
-+ break;
|
|
|
-+ case REL_RELATIVE:
|
|
|
-+ *reloc_addr = (size_t)base + addend;
|
|
|
-+ break;
|
|
|
-+ case REL_SYM_OR_REL:
|
|
|
-+ if (sym) *reloc_addr = sym_val + addend;
|
|
|
-+ else *reloc_addr = (size_t)base + addend;
|
|
|
-+ break;
|
|
|
-+ case REL_COPY:
|
|
|
-+ memcpy(reloc_addr, (void *)sym_val, sym->st_size);
|
|
|
-+ break;
|
|
|
-+ case REL_OFFSET32:
|
|
|
-+ *(uint32_t *)reloc_addr = sym_val + addend
|
|
|
-+ - (size_t)reloc_addr;
|
|
|
-+ break;
|
|
|
-+ case REL_FUNCDESC:
|
|
|
-+ *reloc_addr = def.sym ? (size_t)(def.dso->funcdescs
|
|
|
-+ + (def.sym - def.dso->syms)) : 0;
|
|
|
-+ break;
|
|
|
-+ case REL_FUNCDESC_VAL:
|
|
|
-+ if ((sym->st_info&0xf) == STT_SECTION) *reloc_addr += sym_val;
|
|
|
-+ else *reloc_addr = sym_val;
|
|
|
-+ reloc_addr[1] = def.sym ? (size_t)def.dso->got : 0;
|
|
|
-+ break;
|
|
|
-+ case REL_DTPMOD:
|
|
|
-+ *reloc_addr = def.dso->tls_id;
|
|
|
-+ break;
|
|
|
-+ case REL_DTPOFF:
|
|
|
-+ *reloc_addr = tls_val + addend - DTP_OFFSET;
|
|
|
-+ break;
|
|
|
-+#ifdef TLS_ABOVE_TP
|
|
|
-+ case REL_TPOFF:
|
|
|
-+ *reloc_addr = tls_val + def.dso->tls.offset + TPOFF_K + addend;
|
|
|
-+ break;
|
|
|
-+#else
|
|
|
-+ case REL_TPOFF:
|
|
|
-+ *reloc_addr = tls_val - def.dso->tls.offset + addend;
|
|
|
-+ break;
|
|
|
-+ case REL_TPOFF_NEG:
|
|
|
-+ *reloc_addr = def.dso->tls.offset - tls_val + addend;
|
|
|
-+ break;
|
|
|
-+#endif
|
|
|
-+ case REL_TLSDESC:
|
|
|
-+ if (stride<3) addend = reloc_addr[1];
|
|
|
-+ if (runtime && def.dso->tls_id >= static_tls_cnt) {
|
|
|
-+ struct td_index *new = malloc(sizeof *new);
|
|
|
-+ if (!new) {
|
|
|
-+ error(
|
|
|
-+ "Error relocating %s: cannot allocate TLSDESC for %s",
|
|
|
-+ dso->name, sym ? name : "(local)" );
|
|
|
-+ longjmp(*rtld_fail, 1);
|
|
|
-+ }
|
|
|
-+ new->next = dso->td_index;
|
|
|
-+ dso->td_index = new;
|
|
|
-+ new->args[0] = def.dso->tls_id;
|
|
|
-+ new->args[1] = tls_val + addend;
|
|
|
-+ reloc_addr[0] = (size_t)__tlsdesc_dynamic;
|
|
|
-+ reloc_addr[1] = (size_t)new;
|
|
|
-+ } else {
|
|
|
-+ reloc_addr[0] = (size_t)__tlsdesc_static;
|
|
|
-+#ifdef TLS_ABOVE_TP
|
|
|
-+ reloc_addr[1] = tls_val + def.dso->tls.offset
|
|
|
-+ + TPOFF_K + addend;
|
|
|
-+#else
|
|
|
-+ reloc_addr[1] = tls_val - def.dso->tls.offset
|
|
|
-+ + addend;
|
|
|
-+#endif
|
|
|
-+ }
|
|
|
-+ break;
|
|
|
-+ default:
|
|
|
-+ error("Error relocating %s: unsupported relocation type %d",
|
|
|
-+ dso->name, type);
|
|
|
-+ if (runtime) longjmp(*rtld_fail, 1);
|
|
|
-+ continue;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* A huge hack: to make up for the wastefulness of shared libraries
|
|
|
-+ * needing at least a page of dirty memory even if they have no global
|
|
|
-+ * data, we reclaim the gaps at the beginning and end of writable maps
|
|
|
-+ * and "donate" them to the heap by setting up minimal malloc
|
|
|
-+ * structures and then freeing them. */
|
|
|
-+
|
|
|
-+static void reclaim(struct dso *dso, size_t start, size_t end)
|
|
|
-+{
|
|
|
-+ size_t *a, *z;
|
|
|
-+ if (start >= dso->relro_start && start < dso->relro_end) start = dso->relro_end;
|
|
|
-+ if (end >= dso->relro_start && end < dso->relro_end) end = dso->relro_start;
|
|
|
-+ start = start + 6*sizeof(size_t)-1 & -4*sizeof(size_t);
|
|
|
-+ end = (end & -4*sizeof(size_t)) - 2*sizeof(size_t);
|
|
|
-+ if (start>end || end-start < 4*sizeof(size_t)) return;
|
|
|
-+ a = laddr(dso, start);
|
|
|
-+ z = laddr(dso, end);
|
|
|
-+ a[-2] = 1;
|
|
|
-+ a[-1] = z[0] = end-start + 2*sizeof(size_t) | 1;
|
|
|
-+ z[1] = 1;
|
|
|
-+ free(a);
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void reclaim_gaps(struct dso *dso)
|
|
|
-+{
|
|
|
-+ Phdr *ph = dso->phdr;
|
|
|
-+ size_t phcnt = dso->phnum;
|
|
|
-+
|
|
|
-+ if (DL_FDPIC) return; // FIXME
|
|
|
-+ for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) {
|
|
|
-+ if (ph->p_type!=PT_LOAD) continue;
|
|
|
-+ if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue;
|
|
|
-+ reclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr);
|
|
|
-+ reclaim(dso, ph->p_vaddr+ph->p_memsz,
|
|
|
-+ ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE);
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
|
|
|
-+{
|
|
|
-+ static int no_map_fixed;
|
|
|
-+ char *q;
|
|
|
-+ if (!no_map_fixed) {
|
|
|
-+ q = mmap(p, n, prot, flags|MAP_FIXED, fd, off);
|
|
|
-+ if (!DL_NOMMU_SUPPORT || q != MAP_FAILED || errno != EINVAL)
|
|
|
-+ return q;
|
|
|
-+ no_map_fixed = 1;
|
|
|
-+ }
|
|
|
-+ /* Fallbacks for MAP_FIXED failure on NOMMU kernels. */
|
|
|
-+ if (flags & MAP_ANONYMOUS) {
|
|
|
-+ memset(p, 0, n);
|
|
|
-+ return p;
|
|
|
-+ }
|
|
|
-+ ssize_t r;
|
|
|
-+ if (lseek(fd, off, SEEK_SET) < 0) return MAP_FAILED;
|
|
|
-+ for (q=p; n; q+=r, off+=r, n-=r) {
|
|
|
-+ r = read(fd, q, n);
|
|
|
-+ if (r < 0 && errno != EINTR) return MAP_FAILED;
|
|
|
-+ if (!r) {
|
|
|
-+ memset(q, 0, n);
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ return p;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void unmap_library(struct dso *dso)
|
|
|
-+{
|
|
|
-+ if (dso->loadmap) {
|
|
|
-+ size_t i;
|
|
|
-+ for (i=0; i<dso->loadmap->nsegs; i++) {
|
|
|
-+ if (!dso->loadmap->segs[i].p_memsz)
|
|
|
-+ continue;
|
|
|
-+ munmap((void *)dso->loadmap->segs[i].addr,
|
|
|
-+ dso->loadmap->segs[i].p_memsz);
|
|
|
-+ }
|
|
|
-+ free(dso->loadmap);
|
|
|
-+ } else if (dso->map && dso->map_len) {
|
|
|
-+ munmap(dso->map, dso->map_len);
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void *map_library(int fd, struct dso *dso)
|
|
|
-+{
|
|
|
-+ Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
|
|
|
-+ void *allocated_buf=0;
|
|
|
-+ size_t phsize;
|
|
|
-+ size_t addr_min=SIZE_MAX, addr_max=0, map_len;
|
|
|
-+ size_t this_min, this_max;
|
|
|
-+ size_t nsegs = 0;
|
|
|
-+ off_t off_start;
|
|
|
-+ Ehdr *eh;
|
|
|
-+ Phdr *ph, *ph0;
|
|
|
-+ unsigned prot;
|
|
|
-+ unsigned char *map=MAP_FAILED, *base;
|
|
|
-+ size_t dyn=0;
|
|
|
-+ size_t tls_image=0;
|
|
|
-+ size_t i;
|
|
|
-+
|
|
|
-+ ssize_t l = read(fd, buf, sizeof buf);
|
|
|
-+ eh = buf;
|
|
|
-+ if (l<0) return 0;
|
|
|
-+ if (l<sizeof *eh || (eh->e_type != ET_DYN && eh->e_type != ET_EXEC))
|
|
|
-+ goto noexec;
|
|
|
-+ phsize = eh->e_phentsize * eh->e_phnum;
|
|
|
-+ if (phsize > sizeof buf - sizeof *eh) {
|
|
|
-+ allocated_buf = malloc(phsize);
|
|
|
-+ if (!allocated_buf) return 0;
|
|
|
-+ l = pread(fd, allocated_buf, phsize, eh->e_phoff);
|
|
|
-+ if (l < 0) goto error;
|
|
|
-+ if (l != phsize) goto noexec;
|
|
|
-+ ph = ph0 = allocated_buf;
|
|
|
-+ } else if (eh->e_phoff + phsize > l) {
|
|
|
-+ l = pread(fd, buf+1, phsize, eh->e_phoff);
|
|
|
-+ if (l < 0) goto error;
|
|
|
-+ if (l != phsize) goto noexec;
|
|
|
-+ ph = ph0 = (void *)(buf + 1);
|
|
|
-+ } else {
|
|
|
-+ ph = ph0 = (void *)((char *)buf + eh->e_phoff);
|
|
|
-+ }
|
|
|
-+ for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
|
|
|
-+ if (ph->p_type == PT_DYNAMIC) {
|
|
|
-+ dyn = ph->p_vaddr;
|
|
|
-+ } else if (ph->p_type == PT_TLS) {
|
|
|
-+ tls_image = ph->p_vaddr;
|
|
|
-+ dso->tls.align = ph->p_align;
|
|
|
-+ dso->tls.len = ph->p_filesz;
|
|
|
-+ dso->tls.size = ph->p_memsz;
|
|
|
-+ } else if (ph->p_type == PT_GNU_RELRO) {
|
|
|
-+ dso->relro_start = ph->p_vaddr & -PAGE_SIZE;
|
|
|
-+ dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
|
|
|
-+ }
|
|
|
-+ if (ph->p_type != PT_LOAD) continue;
|
|
|
-+ nsegs++;
|
|
|
-+ if (ph->p_vaddr < addr_min) {
|
|
|
-+ addr_min = ph->p_vaddr;
|
|
|
-+ off_start = ph->p_offset;
|
|
|
-+ prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
|
|
|
-+ ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
|
|
|
-+ ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
|
|
|
-+ }
|
|
|
-+ if (ph->p_vaddr+ph->p_memsz > addr_max) {
|
|
|
-+ addr_max = ph->p_vaddr+ph->p_memsz;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ if (!dyn) goto noexec;
|
|
|
-+ if (DL_FDPIC && !(eh->e_flags & FDPIC_CONSTDISP_FLAG)) {
|
|
|
-+ dso->loadmap = calloc(1, sizeof *dso->loadmap
|
|
|
-+ + nsegs * sizeof *dso->loadmap->segs);
|
|
|
-+ if (!dso->loadmap) goto error;
|
|
|
-+ dso->loadmap->nsegs = nsegs;
|
|
|
-+ for (ph=ph0, i=0; i<nsegs; ph=(void *)((char *)ph+eh->e_phentsize)) {
|
|
|
-+ if (ph->p_type != PT_LOAD) continue;
|
|
|
-+ prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
|
|
|
-+ ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
|
|
|
-+ ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
|
|
|
-+ map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1),
|
|
|
-+ prot, MAP_PRIVATE,
|
|
|
-+ fd, ph->p_offset & -PAGE_SIZE);
|
|
|
-+ if (map == MAP_FAILED) {
|
|
|
-+ unmap_library(dso);
|
|
|
-+ goto error;
|
|
|
-+ }
|
|
|
-+ dso->loadmap->segs[i].addr = (size_t)map +
|
|
|
-+ (ph->p_vaddr & PAGE_SIZE-1);
|
|
|
-+ dso->loadmap->segs[i].p_vaddr = ph->p_vaddr;
|
|
|
-+ dso->loadmap->segs[i].p_memsz = ph->p_memsz;
|
|
|
-+ i++;
|
|
|
-+ if (prot & PROT_WRITE) {
|
|
|
-+ size_t brk = (ph->p_vaddr & PAGE_SIZE-1)
|
|
|
-+ + ph->p_filesz;
|
|
|
-+ size_t pgbrk = brk + PAGE_SIZE-1 & -PAGE_SIZE;
|
|
|
-+ size_t pgend = brk + ph->p_memsz - ph->p_filesz
|
|
|
-+ + PAGE_SIZE-1 & -PAGE_SIZE;
|
|
|
-+ if (pgend > pgbrk && mmap_fixed(map+pgbrk,
|
|
|
-+ pgend-pgbrk, prot,
|
|
|
-+ MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
|
|
|
-+ -1, off_start) == MAP_FAILED)
|
|
|
-+ goto error;
|
|
|
-+ memset(map + brk, 0, pgbrk-brk);
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ map = (void *)dso->loadmap->segs[0].addr;
|
|
|
-+ map_len = 0;
|
|
|
-+ goto done_mapping;
|
|
|
-+ }
|
|
|
-+ addr_max += PAGE_SIZE-1;
|
|
|
-+ addr_max &= -PAGE_SIZE;
|
|
|
-+ addr_min &= -PAGE_SIZE;
|
|
|
-+ off_start &= -PAGE_SIZE;
|
|
|
-+ map_len = addr_max - addr_min + off_start;
|
|
|
-+ /* The first time, we map too much, possibly even more than
|
|
|
-+ * the length of the file. This is okay because we will not
|
|
|
-+ * use the invalid part; we just need to reserve the right
|
|
|
-+ * amount of virtual address space to map over later. */
|
|
|
-+ map = DL_NOMMU_SUPPORT
|
|
|
-+ ? mmap((void *)addr_min, map_len, PROT_READ|PROT_WRITE|PROT_EXEC,
|
|
|
-+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
|
|
|
-+ : mmap((void *)addr_min, map_len, prot,
|
|
|
-+ MAP_PRIVATE, fd, off_start);
|
|
|
-+ if (map==MAP_FAILED) goto error;
|
|
|
-+ dso->map = map;
|
|
|
-+ dso->map_len = map_len;
|
|
|
-+ /* If the loaded file is not relocatable and the requested address is
|
|
|
-+ * not available, then the load operation must fail. */
|
|
|
-+ if (eh->e_type != ET_DYN && addr_min && map!=(void *)addr_min) {
|
|
|
-+ errno = EBUSY;
|
|
|
-+ goto error;
|
|
|
-+ }
|
|
|
-+ base = map - addr_min;
|
|
|
-+ dso->phdr = 0;
|
|
|
-+ dso->phnum = 0;
|
|
|
-+ for (ph=ph0, i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
|
|
|
-+ if (ph->p_type != PT_LOAD) continue;
|
|
|
-+ /* Check if the programs headers are in this load segment, and
|
|
|
-+ * if so, record the address for use by dl_iterate_phdr. */
|
|
|
-+ if (!dso->phdr && eh->e_phoff >= ph->p_offset
|
|
|
-+ && eh->e_phoff+phsize <= ph->p_offset+ph->p_filesz) {
|
|
|
-+ dso->phdr = (void *)(base + ph->p_vaddr
|
|
|
-+ + (eh->e_phoff-ph->p_offset));
|
|
|
-+ dso->phnum = eh->e_phnum;
|
|
|
-+ dso->phentsize = eh->e_phentsize;
|
|
|
-+ }
|
|
|
-+ /* Reuse the existing mapping for the lowest-address LOAD */
|
|
|
-+ if ((ph->p_vaddr & -PAGE_SIZE) == addr_min && !DL_NOMMU_SUPPORT)
|
|
|
-+ continue;
|
|
|
-+ this_min = ph->p_vaddr & -PAGE_SIZE;
|
|
|
-+ this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;
|
|
|
-+ off_start = ph->p_offset & -PAGE_SIZE;
|
|
|
-+ prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
|
|
|
-+ ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
|
|
|
-+ ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
|
|
|
-+ if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
|
|
|
-+ goto error;
|
|
|
-+ if (ph->p_memsz > ph->p_filesz) {
|
|
|
-+ size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
|
|
|
-+ size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
|
|
|
-+ memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
|
|
|
-+ if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
|
|
|
-+ goto error;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
|
|
|
-+ if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
|
|
|
-+ if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC)
|
|
|
-+ && errno != ENOSYS)
|
|
|
-+ goto error;
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
-+done_mapping:
|
|
|
-+ dso->base = base;
|
|
|
-+ dso->dynv = laddr(dso, dyn);
|
|
|
-+ if (dso->tls.size) dso->tls.image = laddr(dso, tls_image);
|
|
|
-+ if (!runtime) reclaim_gaps(dso);
|
|
|
-+ free(allocated_buf);
|
|
|
-+ return map;
|
|
|
-+noexec:
|
|
|
-+ errno = ENOEXEC;
|
|
|
-+error:
|
|
|
-+ if (map!=MAP_FAILED) unmap_library(dso);
|
|
|
-+ free(allocated_buf);
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int path_open(const char *name, const char *s, char *buf, size_t buf_size)
|
|
|
-+{
|
|
|
-+ size_t l;
|
|
|
-+ int fd;
|
|
|
-+ for (;;) {
|
|
|
-+ s += strspn(s, ":\n");
|
|
|
-+ l = strcspn(s, ":\n");
|
|
|
-+ if (l-1 >= INT_MAX) return -1;
|
|
|
-+ if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) {
|
|
|
-+ if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd;
|
|
|
-+ switch (errno) {
|
|
|
-+ case ENOENT:
|
|
|
-+ case ENOTDIR:
|
|
|
-+ case EACCES:
|
|
|
-+ case ENAMETOOLONG:
|
|
|
-+ break;
|
|
|
-+ default:
|
|
|
-+ /* Any negative value but -1 will inhibit
|
|
|
-+ * futher path search. */
|
|
|
-+ return -2;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ s += l;
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)
|
|
|
-+{
|
|
|
-+ size_t n, l;
|
|
|
-+ const char *s, *t, *origin;
|
|
|
-+ char *d;
|
|
|
-+ if (p->rpath || !p->rpath_orig) return 0;
|
|
|
-+ if (!strchr(p->rpath_orig, '$')) {
|
|
|
-+ p->rpath = p->rpath_orig;
|
|
|
-+ return 0;
|
|
|
-+ }
|
|
|
-+ n = 0;
|
|
|
-+ s = p->rpath_orig;
|
|
|
-+ while ((t=strchr(s, '$'))) {
|
|
|
-+ if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9))
|
|
|
-+ return 0;
|
|
|
-+ s = t+1;
|
|
|
-+ n++;
|
|
|
-+ }
|
|
|
-+ if (n > SSIZE_MAX/PATH_MAX) return 0;
|
|
|
-+
|
|
|
-+ if (p->kernel_mapped) {
|
|
|
-+ /* $ORIGIN searches cannot be performed for the main program
|
|
|
-+ * when it is suid/sgid/AT_SECURE. This is because the
|
|
|
-+ * pathname is under the control of the caller of execve.
|
|
|
-+ * For libraries, however, $ORIGIN can be processed safely
|
|
|
-+ * since the library's pathname came from a trusted source
|
|
|
-+ * (either system paths or a call to dlopen). */
|
|
|
-+ if (libc.secure)
|
|
|
-+ return 0;
|
|
|
-+ l = readlink("/proc/self/exe", buf, buf_size);
|
|
|
-+ if (l == -1) switch (errno) {
|
|
|
-+ case ENOENT:
|
|
|
-+ case ENOTDIR:
|
|
|
-+ case EACCES:
|
|
|
-+ break;
|
|
|
-+ default:
|
|
|
-+ return -1;
|
|
|
-+ }
|
|
|
-+ if (l >= buf_size)
|
|
|
-+ return 0;
|
|
|
-+ buf[l] = 0;
|
|
|
-+ origin = buf;
|
|
|
-+ } else {
|
|
|
-+ origin = p->name;
|
|
|
-+ }
|
|
|
-+ t = strrchr(origin, '/');
|
|
|
-+ l = t ? t-origin : 0;
|
|
|
-+ p->rpath = malloc(strlen(p->rpath_orig) + n*l + 1);
|
|
|
-+ if (!p->rpath) return -1;
|
|
|
-+
|
|
|
-+ d = p->rpath;
|
|
|
-+ s = p->rpath_orig;
|
|
|
-+ while ((t=strchr(s, '$'))) {
|
|
|
-+ memcpy(d, s, t-s);
|
|
|
-+ d += t-s;
|
|
|
-+ memcpy(d, origin, l);
|
|
|
-+ d += l;
|
|
|
-+ /* It was determined previously that the '$' is followed
|
|
|
-+ * either by "ORIGIN" or "{ORIGIN}". */
|
|
|
-+ s = t + 7 + 2*(t[1]=='{');
|
|
|
-+ }
|
|
|
-+ strcpy(d, s);
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void decode_dyn(struct dso *p)
|
|
|
-+{
|
|
|
-+ size_t dyn[DYN_CNT];
|
|
|
-+ decode_vec(p->dynv, dyn, DYN_CNT);
|
|
|
-+ p->syms = laddr(p, dyn[DT_SYMTAB]);
|
|
|
-+ p->strings = laddr(p, dyn[DT_STRTAB]);
|
|
|
-+ if (dyn[0]&(1<<DT_HASH))
|
|
|
-+ p->hashtab = laddr(p, dyn[DT_HASH]);
|
|
|
-+ if (dyn[0]&(1<<DT_RPATH))
|
|
|
-+ p->rpath_orig = p->strings + dyn[DT_RPATH];
|
|
|
-+ if (dyn[0]&(1<<DT_RUNPATH))
|
|
|
-+ p->rpath_orig = p->strings + dyn[DT_RUNPATH];
|
|
|
-+ if (dyn[0]&(1<<DT_PLTGOT))
|
|
|
-+ p->got = laddr(p, dyn[DT_PLTGOT]);
|
|
|
-+ if (search_vec(p->dynv, dyn, DT_GNU_HASH))
|
|
|
-+ p->ghashtab = laddr(p, *dyn);
|
|
|
-+ if (search_vec(p->dynv, dyn, DT_VERSYM))
|
|
|
-+ p->versym = laddr(p, *dyn);
|
|
|
-+}
|
|
|
-+
|
|
|
-+static size_t count_syms(struct dso *p)
|
|
|
-+{
|
|
|
-+ if (p->hashtab) return p->hashtab[1];
|
|
|
-+
|
|
|
-+ size_t nsym, i;
|
|
|
-+ uint32_t *buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4);
|
|
|
-+ uint32_t *hashval;
|
|
|
-+ for (i = nsym = 0; i < p->ghashtab[0]; i++) {
|
|
|
-+ if (buckets[i] > nsym)
|
|
|
-+ nsym = buckets[i];
|
|
|
-+ }
|
|
|
-+ if (nsym) {
|
|
|
-+ hashval = buckets + p->ghashtab[0] + (nsym - p->ghashtab[1]);
|
|
|
-+ do nsym++;
|
|
|
-+ while (!(*hashval++ & 1));
|
|
|
-+ }
|
|
|
-+ return nsym;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void *dl_mmap(size_t n)
|
|
|
-+{
|
|
|
-+ void *p;
|
|
|
-+ int prot = PROT_READ|PROT_WRITE, flags = MAP_ANONYMOUS|MAP_PRIVATE;
|
|
|
-+#ifdef SYS_mmap2
|
|
|
-+ p = (void *)__syscall(SYS_mmap2, 0, n, prot, flags, -1, 0);
|
|
|
-+#else
|
|
|
-+ p = (void *)__syscall(SYS_mmap, 0, n, prot, flags, -1, 0);
|
|
|
-+#endif
|
|
|
-+ return p == MAP_FAILED ? 0 : p;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void makefuncdescs(struct dso *p)
|
|
|
-+{
|
|
|
-+ static int self_done;
|
|
|
-+ size_t nsym = count_syms(p);
|
|
|
-+ size_t i, size = nsym * sizeof(*p->funcdescs);
|
|
|
-+
|
|
|
-+ if (!self_done) {
|
|
|
-+ p->funcdescs = dl_mmap(size);
|
|
|
-+ self_done = 1;
|
|
|
-+ } else {
|
|
|
-+ p->funcdescs = malloc(size);
|
|
|
-+ }
|
|
|
-+ if (!p->funcdescs) {
|
|
|
-+ if (!runtime) a_crash();
|
|
|
-+ error("Error allocating function descriptors for %s", p->name);
|
|
|
-+ longjmp(*rtld_fail, 1);
|
|
|
-+ }
|
|
|
-+ for (i=0; i<nsym; i++) {
|
|
|
-+ if ((p->syms[i].st_info&0xf)==STT_FUNC && p->syms[i].st_shndx) {
|
|
|
-+ p->funcdescs[i].addr = laddr(p, p->syms[i].st_value);
|
|
|
-+ p->funcdescs[i].got = p->got;
|
|
|
-+ } else {
|
|
|
-+ p->funcdescs[i].addr = 0;
|
|
|
-+ p->funcdescs[i].got = 0;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+static struct dso *load_library(const char *name, struct dso *needed_by)
|
|
|
-+{
|
|
|
-+ char buf[2*NAME_MAX+2];
|
|
|
-+ const char *pathname;
|
|
|
-+ unsigned char *map;
|
|
|
-+ struct dso *p, temp_dso = {0};
|
|
|
-+ int fd;
|
|
|
-+ struct stat st;
|
|
|
-+ size_t alloc_size;
|
|
|
-+ int n_th = 0;
|
|
|
-+ int is_self = 0;
|
|
|
-+
|
|
|
-+ if (!*name) {
|
|
|
-+ errno = EINVAL;
|
|
|
-+ return 0;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Catch and block attempts to reload the implementation itself */
|
|
|
-+ if (name[0]=='l' && name[1]=='i' && name[2]=='b') {
|
|
|
-+ static const char *rp, reserved[] =
|
|
|
-+ "c\0pthread\0rt\0m\0dl\0util\0xnet\0";
|
|
|
-+ char *z = strchr(name, '.');
|
|
|
-+ if (z) {
|
|
|
-+ size_t l = z-name;
|
|
|
-+ for (rp=reserved; *rp && strncmp(name+3, rp, l-3); rp+=strlen(rp)+1);
|
|
|
-+ if (*rp) {
|
|
|
-+ if (ldd_mode) {
|
|
|
-+ /* Track which names have been resolved
|
|
|
-+ * and only report each one once. */
|
|
|
-+ static unsigned reported;
|
|
|
-+ unsigned mask = 1U<<(rp-reserved);
|
|
|
-+ if (!(reported & mask)) {
|
|
|
-+ reported |= mask;
|
|
|
-+ dprintf(1, "\t%s => %s (%p)\n",
|
|
|
-+ name, ldso.name,
|
|
|
-+ ldso.base);
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ is_self = 1;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ if (!strcmp(name, ldso.name)) is_self = 1;
|
|
|
-+ if (is_self) {
|
|
|
-+ if (!ldso.prev) {
|
|
|
-+ tail->next = &ldso;
|
|
|
-+ ldso.prev = tail;
|
|
|
-+ tail = ldso.next ? ldso.next : &ldso;
|
|
|
-+ }
|
|
|
-+ return &ldso;
|
|
|
-+ }
|
|
|
-+ if (strchr(name, '/')) {
|
|
|
-+ pathname = name;
|
|
|
-+ fd = open(name, O_RDONLY|O_CLOEXEC);
|
|
|
-+ } else {
|
|
|
-+ /* Search for the name to see if it's already loaded */
|
|
|
-+ for (p=head->next; p; p=p->next) {
|
|
|
-+ if (p->shortname && !strcmp(p->shortname, name)) {
|
|
|
-+ p->refcnt++;
|
|
|
-+ return p;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ if (strlen(name) > NAME_MAX) return 0;
|
|
|
-+ fd = -1;
|
|
|
-+ if (env_path) fd = path_open(name, env_path, buf, sizeof buf);
|
|
|
-+ for (p=needed_by; fd == -1 && p; p=p->needed_by) {
|
|
|
-+ if (fixup_rpath(p, buf, sizeof buf) < 0)
|
|
|
-+ fd = -2; /* Inhibit further search. */
|
|
|
-+ if (p->rpath)
|
|
|
-+ fd = path_open(name, p->rpath, buf, sizeof buf);
|
|
|
-+ }
|
|
|
-+ if (fd == -1) {
|
|
|
-+ if (!sys_path) {
|
|
|
-+ char *prefix = 0;
|
|
|
-+ size_t prefix_len;
|
|
|
-+ if (ldso.name[0]=='/') {
|
|
|
-+ char *s, *t, *z;
|
|
|
-+ for (s=t=z=ldso.name; *s; s++)
|
|
|
-+ if (*s=='/') z=t, t=s;
|
|
|
-+ prefix_len = z-ldso.name;
|
|
|
-+ if (prefix_len < PATH_MAX)
|
|
|
-+ prefix = ldso.name;
|
|
|
-+ }
|
|
|
-+ if (!prefix) {
|
|
|
-+ prefix = "";
|
|
|
-+ prefix_len = 0;
|
|
|
-+ }
|
|
|
-+ char etc_ldso_path[prefix_len + 1
|
|
|
-+ + sizeof "/etc/ld-musl-" LDSO_ARCH ".path"];
|
|
|
-+ snprintf(etc_ldso_path, sizeof etc_ldso_path,
|
|
|
-+ "%.*s/etc/ld-musl-" LDSO_ARCH ".path",
|
|
|
-+ (int)prefix_len, prefix);
|
|
|
-+ FILE *f = fopen(etc_ldso_path, "rbe");
|
|
|
-+ if (f) {
|
|
|
-+ if (getdelim(&sys_path, (size_t[1]){0}, 0, f) <= 0) {
|
|
|
-+ free(sys_path);
|
|
|
-+ sys_path = "";
|
|
|
-+ }
|
|
|
-+ fclose(f);
|
|
|
-+ } else if (errno != ENOENT) {
|
|
|
-+ sys_path = "";
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";
|
|
|
-+ fd = path_open(name, sys_path, buf, sizeof buf);
|
|
|
-+ }
|
|
|
-+ pathname = buf;
|
|
|
-+ }
|
|
|
-+ if (fd < 0) return 0;
|
|
|
-+ if (fstat(fd, &st) < 0) {
|
|
|
-+ close(fd);
|
|
|
-+ return 0;
|
|
|
-+ }
|
|
|
-+ for (p=head->next; p; p=p->next) {
|
|
|
-+ if (p->dev == st.st_dev && p->ino == st.st_ino) {
|
|
|
-+ /* If this library was previously loaded with a
|
|
|
-+ * pathname but a search found the same inode,
|
|
|
-+ * setup its shortname so it can be found by name. */
|
|
|
-+ if (!p->shortname && pathname != name)
|
|
|
-+ p->shortname = strrchr(p->name, '/')+1;
|
|
|
-+ close(fd);
|
|
|
-+ p->refcnt++;
|
|
|
-+ return p;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ map = noload ? 0 : map_library(fd, &temp_dso);
|
|
|
-+ close(fd);
|
|
|
-+ if (!map) return 0;
|
|
|
-+
|
|
|
-+ /* Allocate storage for the new DSO. When there is TLS, this
|
|
|
-+ * storage must include a reservation for all pre-existing
|
|
|
-+ * threads to obtain copies of both the new TLS, and an
|
|
|
-+ * extended DTV capable of storing an additional slot for
|
|
|
-+ * the newly-loaded DSO. */
|
|
|
-+ alloc_size = sizeof *p + strlen(pathname) + 1;
|
|
|
-+ if (runtime && temp_dso.tls.image) {
|
|
|
-+ size_t per_th = temp_dso.tls.size + temp_dso.tls.align
|
|
|
-+ + sizeof(void *) * (tls_cnt+3);
|
|
|
-+ n_th = libc.threads_minus_1 + 1;
|
|
|
-+ if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX;
|
|
|
-+ else alloc_size += n_th * per_th;
|
|
|
-+ }
|
|
|
-+ p = calloc(1, alloc_size);
|
|
|
-+ if (!p) {
|
|
|
-+ unmap_library(&temp_dso);
|
|
|
-+ return 0;
|
|
|
-+ }
|
|
|
-+ memcpy(p, &temp_dso, sizeof temp_dso);
|
|
|
-+ decode_dyn(p);
|
|
|
-+ p->dev = st.st_dev;
|
|
|
-+ p->ino = st.st_ino;
|
|
|
-+ p->refcnt = 1;
|
|
|
-+ p->needed_by = needed_by;
|
|
|
-+ p->name = p->buf;
|
|
|
-+ strcpy(p->name, pathname);
|
|
|
-+ /* Add a shortname only if name arg was not an explicit pathname. */
|
|
|
-+ if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
|
|
|
-+ if (p->tls.image) {
|
|
|
-+ p->tls_id = ++tls_cnt;
|
|
|
-+ tls_align = MAXP2(tls_align, p->tls.align);
|
|
|
-+#ifdef TLS_ABOVE_TP
|
|
|
-+ p->tls.offset = tls_offset + ( (tls_align-1) &
|
|
|
-+ -(tls_offset + (uintptr_t)p->tls.image) );
|
|
|
-+ tls_offset += p->tls.size;
|
|
|
-+#else
|
|
|
-+ tls_offset += p->tls.size + p->tls.align - 1;
|
|
|
-+ tls_offset -= (tls_offset + (uintptr_t)p->tls.image)
|
|
|
-+ & (p->tls.align-1);
|
|
|
-+ p->tls.offset = tls_offset;
|
|
|
-+#endif
|
|
|
-+ p->new_dtv = (void *)(-sizeof(size_t) &
|
|
|
-+ (uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));
|
|
|
-+ p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));
|
|
|
-+ if (tls_tail) tls_tail->next = &p->tls;
|
|
|
-+ else libc.tls_head = &p->tls;
|
|
|
-+ tls_tail = &p->tls;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ tail->next = p;
|
|
|
-+ p->prev = tail;
|
|
|
-+ tail = p;
|
|
|
-+
|
|
|
-+ if (DL_FDPIC) makefuncdescs(p);
|
|
|
-+
|
|
|
-+ if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base);
|
|
|
-+
|
|
|
-+ return p;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void load_deps(struct dso *p)
|
|
|
-+{
|
|
|
-+ size_t i, ndeps=0;
|
|
|
-+ struct dso ***deps = &p->deps, **tmp, *dep;
|
|
|
-+ for (; p; p=p->next) {
|
|
|
-+ for (i=0; p->dynv[i]; i+=2) {
|
|
|
-+ if (p->dynv[i] != DT_NEEDED) continue;
|
|
|
-+ dep = load_library(p->strings + p->dynv[i+1], p);
|
|
|
-+ if (!dep) {
|
|
|
-+ error("Error loading shared library %s: %m (needed by %s)",
|
|
|
-+ p->strings + p->dynv[i+1], p->name);
|
|
|
-+ if (runtime) longjmp(*rtld_fail, 1);
|
|
|
-+ continue;
|
|
|
-+ }
|
|
|
-+ if (runtime) {
|
|
|
-+ tmp = realloc(*deps, sizeof(*tmp)*(ndeps+2));
|
|
|
-+ if (!tmp) longjmp(*rtld_fail, 1);
|
|
|
-+ tmp[ndeps++] = dep;
|
|
|
-+ tmp[ndeps] = 0;
|
|
|
-+ *deps = tmp;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void load_preload(char *s)
|
|
|
-+{
|
|
|
-+ int tmp;
|
|
|
-+ char *z;
|
|
|
-+ for (z=s; *z; s=z) {
|
|
|
-+ for ( ; *s && (isspace(*s) || *s==':'); s++);
|
|
|
-+ for (z=s; *z && !isspace(*z) && *z!=':'; z++);
|
|
|
-+ tmp = *z;
|
|
|
-+ *z = 0;
|
|
|
-+ load_library(s, 0);
|
|
|
-+ *z = tmp;
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void make_global(struct dso *p)
|
|
|
-+{
|
|
|
-+ for (; p; p=p->next) p->global = 1;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void do_mips_relocs(struct dso *p, size_t *got)
|
|
|
-+{
|
|
|
-+ size_t i, j, rel[2];
|
|
|
-+ unsigned char *base = p->base;
|
|
|
-+ i=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO);
|
|
|
-+ if (p==&ldso) {
|
|
|
-+ got += i;
|
|
|
-+ } else {
|
|
|
-+ while (i--) *got++ += (size_t)base;
|
|
|
-+ }
|
|
|
-+ j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);
|
|
|
-+ i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);
|
|
|
-+ Sym *sym = p->syms + j;
|
|
|
-+ rel[0] = (unsigned char *)got - base;
|
|
|
-+ for (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) {
|
|
|
-+ rel[1] = sym-p->syms << 8 | R_MIPS_JUMP_SLOT;
|
|
|
-+ do_relocs(p, rel, sizeof rel, 2);
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void reloc_all(struct dso *p)
|
|
|
-+{
|
|
|
-+ size_t dyn[DYN_CNT];
|
|
|
-+ for (; p; p=p->next) {
|
|
|
-+ if (p->relocated) continue;
|
|
|
-+ decode_vec(p->dynv, dyn, DYN_CNT);
|
|
|
-+ if (NEED_MIPS_GOT_RELOCS)
|
|
|
-+ do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT]));
|
|
|
-+ do_relocs(p, laddr(p, dyn[DT_JMPREL]), dyn[DT_PLTRELSZ],
|
|
|
-+ 2+(dyn[DT_PLTREL]==DT_RELA));
|
|
|
-+ do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2);
|
|
|
-+ do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3);
|
|
|
-+
|
|
|
-+ if (head != &ldso && p->relro_start != p->relro_end &&
|
|
|
-+ mprotect(laddr(p, p->relro_start), p->relro_end-p->relro_start, PROT_READ)
|
|
|
-+ && errno != ENOSYS) {
|
|
|
-+ error("Error relocating %s: RELRO protection failed: %m",
|
|
|
-+ p->name);
|
|
|
-+ if (runtime) longjmp(*rtld_fail, 1);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ p->relocated = 1;
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void kernel_mapped_dso(struct dso *p)
|
|
|
-+{
|
|
|
-+ size_t min_addr = -1, max_addr = 0, cnt;
|
|
|
-+ Phdr *ph = p->phdr;
|
|
|
-+ for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) {
|
|
|
-+ if (ph->p_type == PT_DYNAMIC) {
|
|
|
-+ p->dynv = laddr(p, ph->p_vaddr);
|
|
|
-+ } else if (ph->p_type == PT_GNU_RELRO) {
|
|
|
-+ p->relro_start = ph->p_vaddr & -PAGE_SIZE;
|
|
|
-+ p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
|
|
|
-+ }
|
|
|
-+ if (ph->p_type != PT_LOAD) continue;
|
|
|
-+ if (ph->p_vaddr < min_addr)
|
|
|
-+ min_addr = ph->p_vaddr;
|
|
|
-+ if (ph->p_vaddr+ph->p_memsz > max_addr)
|
|
|
-+ max_addr = ph->p_vaddr+ph->p_memsz;
|
|
|
-+ }
|
|
|
-+ min_addr &= -PAGE_SIZE;
|
|
|
-+ max_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE;
|
|
|
-+ p->map = p->base + min_addr;
|
|
|
-+ p->map_len = max_addr - min_addr;
|
|
|
-+ p->kernel_mapped = 1;
|
|
|
-+}
|
|
|
-+
|
|
|
-+void __libc_exit_fini()
|
|
|
-+{
|
|
|
-+ struct dso *p;
|
|
|
-+ size_t dyn[DYN_CNT];
|
|
|
-+ for (p=fini_head; p; p=p->fini_next) {
|
|
|
-+ if (!p->constructed) continue;
|
|
|
-+ decode_vec(p->dynv, dyn, DYN_CNT);
|
|
|
-+ if (dyn[0] & (1<<DT_FINI_ARRAY)) {
|
|
|
-+ size_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t);
|
|
|
-+ size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY])+n;
|
|
|
-+ while (n--) ((void (*)(void))*--fn)();
|
|
|
-+ }
|
|
|
-+#ifndef NO_LEGACY_INITFINI
|
|
|
-+ if ((dyn[0] & (1<<DT_FINI)) && dyn[DT_FINI])
|
|
|
-+ fpaddr(p, dyn[DT_FINI])();
|
|
|
-+#endif
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void do_init_fini(struct dso *p)
|
|
|
-+{
|
|
|
-+ size_t dyn[DYN_CNT];
|
|
|
-+ int need_locking = libc.threads_minus_1;
|
|
|
-+ /* Allow recursive calls that arise when a library calls
|
|
|
-+ * dlopen from one of its constructors, but block any
|
|
|
-+ * other threads until all ctors have finished. */
|
|
|
-+ if (need_locking) pthread_mutex_lock(&init_fini_lock);
|
|
|
-+ for (; p; p=p->prev) {
|
|
|
-+ if (p->constructed) continue;
|
|
|
-+ p->constructed = 1;
|
|
|
-+ decode_vec(p->dynv, dyn, DYN_CNT);
|
|
|
-+ if (dyn[0] & ((1<<DT_FINI) | (1<<DT_FINI_ARRAY))) {
|
|
|
-+ p->fini_next = fini_head;
|
|
|
-+ fini_head = p;
|
|
|
-+ }
|
|
|
-+#ifndef NO_LEGACY_INITFINI
|
|
|
-+ if ((dyn[0] & (1<<DT_INIT)) && dyn[DT_INIT])
|
|
|
-+ fpaddr(p, dyn[DT_INIT])();
|
|
|
-+#endif
|
|
|
-+ if (dyn[0] & (1<<DT_INIT_ARRAY)) {
|
|
|
-+ size_t n = dyn[DT_INIT_ARRAYSZ]/sizeof(size_t);
|
|
|
-+ size_t *fn = laddr(p, dyn[DT_INIT_ARRAY]);
|
|
|
-+ while (n--) ((void (*)(void))*fn++)();
|
|
|
-+ }
|
|
|
-+ if (!need_locking && libc.threads_minus_1) {
|
|
|
-+ need_locking = 1;
|
|
|
-+ pthread_mutex_lock(&init_fini_lock);
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ if (need_locking) pthread_mutex_unlock(&init_fini_lock);
|
|
|
-+}
|
|
|
-+
|
|
|
-+void __libc_start_init(void)
|
|
|
-+{
|
|
|
-+ do_init_fini(tail);
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void dl_debug_state(void)
|
|
|
-+{
|
|
|
-+}
|
|
|
-+
|
|
|
-+weak_alias(dl_debug_state, _dl_debug_state);
|
|
|
-+
|
|
|
-+void __init_tls(size_t *auxv)
|
|
|
-+{
|
|
|
-+}
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+void *__tls_get_new(size_t *v)
|
|
|
-+{
|
|
|
-+ pthread_t self = __pthread_self();
|
|
|
-+
|
|
|
-+ /* Block signals to make accessing new TLS async-signal-safe */
|
|
|
-+ sigset_t set;
|
|
|
-+ __block_all_sigs(&set);
|
|
|
-+ if (v[0]<=(size_t)self->dtv[0]) {
|
|
|
-+ __restore_sigs(&set);
|
|
|
-+ return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* This is safe without any locks held because, if the caller
|
|
|
-+ * is able to request the Nth entry of the DTV, the DSO list
|
|
|
-+ * must be valid at least that far out and it was synchronized
|
|
|
-+ * at program startup or by an already-completed call to dlopen. */
|
|
|
-+ struct dso *p;
|
|
|
-+ for (p=head; p->tls_id != v[0]; p=p->next);
|
|
|
-+
|
|
|
-+ /* Get new DTV space from new DSO if needed */
|
|
|
-+ if (v[0] > (size_t)self->dtv[0]) {
|
|
|
-+ void **newdtv = p->new_dtv +
|
|
|
-+ (v[0]+1)*a_fetch_add(&p->new_dtv_idx,1);
|
|
|
-+ memcpy(newdtv, self->dtv,
|
|
|
-+ ((size_t)self->dtv[0]+1) * sizeof(void *));
|
|
|
-+ newdtv[0] = (void *)v[0];
|
|
|
-+ self->dtv = self->dtv_copy = newdtv;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Get new TLS memory from all new DSOs up to the requested one */
|
|
|
-+ unsigned char *mem;
|
|
|
-+ for (p=head; ; p=p->next) {
|
|
|
-+ if (!p->tls_id || self->dtv[p->tls_id]) continue;
|
|
|
-+ mem = p->new_tls + (p->tls.size + p->tls.align)
|
|
|
-+ * a_fetch_add(&p->new_tls_idx,1);
|
|
|
-+ mem += ((uintptr_t)p->tls.image - (uintptr_t)mem)
|
|
|
-+ & (p->tls.align-1);
|
|
|
-+ self->dtv[p->tls_id] = mem;
|
|
|
-+ memcpy(mem, p->tls.image, p->tls.len);
|
|
|
-+ if (p->tls_id == v[0]) break;
|
|
|
-+ }
|
|
|
-+ __restore_sigs(&set);
|
|
|
-+ return mem + v[1] + DTP_OFFSET;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void update_tls_size()
|
|
|
-+{
|
|
|
-+ libc.tls_cnt = tls_cnt;
|
|
|
-+ libc.tls_align = tls_align;
|
|
|
-+ libc.tls_size = ALIGN(
|
|
|
-+ (1+tls_cnt) * sizeof(void *) +
|
|
|
-+ tls_offset +
|
|
|
-+ sizeof(struct pthread) +
|
|
|
-+ tls_align * 2,
|
|
|
-+ tls_align);
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Stage 1 of the dynamic linker is defined in dlstart.c. It calls the
|
|
|
-+ * following stage 2 and stage 3 functions via primitive symbolic lookup
|
|
|
-+ * since it does not have access to their addresses to begin with. */
|
|
|
-+
|
|
|
-+/* Stage 2 of the dynamic linker is called after relative relocations
|
|
|
-+ * have been processed. It can make function calls to static functions
|
|
|
-+ * and access string literals and static data, but cannot use extern
|
|
|
-+ * symbols. Its job is to perform symbolic relocations on the dynamic
|
|
|
-+ * linker itself, but some of the relocations performed may need to be
|
|
|
-+ * replaced later due to copy relocations in the main program. */
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+void __dls2(unsigned char *base, size_t *sp)
|
|
|
-+{
|
|
|
-+ if (DL_FDPIC) {
|
|
|
-+ void *p1 = (void *)sp[-2];
|
|
|
-+ void *p2 = (void *)sp[-1];
|
|
|
-+ if (!p1) {
|
|
|
-+ size_t *auxv, aux[AUX_CNT];
|
|
|
-+ for (auxv=sp+1+*sp+1; *auxv; auxv++); auxv++;
|
|
|
-+ decode_vec(auxv, aux, AUX_CNT);
|
|
|
-+ if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE];
|
|
|
-+ else ldso.base = (void *)(aux[AT_PHDR] & -4096);
|
|
|
-+ }
|
|
|
-+ app_loadmap = p2 ? p1 : 0;
|
|
|
-+ ldso.loadmap = p2 ? p2 : p1;
|
|
|
-+ ldso.base = laddr(&ldso, 0);
|
|
|
-+ } else {
|
|
|
-+ ldso.base = base;
|
|
|
-+ }
|
|
|
-+ Ehdr *ehdr = (void *)ldso.base;
|
|
|
-+ ldso.name = ldso.shortname = "libc.so";
|
|
|
-+ ldso.global = 1;
|
|
|
-+ ldso.phnum = ehdr->e_phnum;
|
|
|
-+ ldso.phdr = laddr(&ldso, ehdr->e_phoff);
|
|
|
-+ ldso.phentsize = ehdr->e_phentsize;
|
|
|
-+ kernel_mapped_dso(&ldso);
|
|
|
-+ decode_dyn(&ldso);
|
|
|
-+
|
|
|
-+ if (DL_FDPIC) makefuncdescs(&ldso);
|
|
|
-+
|
|
|
-+ /* Prepare storage for to save clobbered REL addends so they
|
|
|
-+ * can be reused in stage 3. There should be very few. If
|
|
|
-+ * something goes wrong and there are a huge number, abort
|
|
|
-+ * instead of risking stack overflow. */
|
|
|
-+ size_t dyn[DYN_CNT];
|
|
|
-+ decode_vec(ldso.dynv, dyn, DYN_CNT);
|
|
|
-+ size_t *rel = laddr(&ldso, dyn[DT_REL]);
|
|
|
-+ size_t rel_size = dyn[DT_RELSZ];
|
|
|
-+ size_t symbolic_rel_cnt = 0;
|
|
|
-+ apply_addends_to = rel;
|
|
|
-+ for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t))
|
|
|
-+ if (!IS_RELATIVE(rel[1], ldso.syms)) symbolic_rel_cnt++;
|
|
|
-+ if (symbolic_rel_cnt >= ADDEND_LIMIT) a_crash();
|
|
|
-+ size_t addends[symbolic_rel_cnt+1];
|
|
|
-+ saved_addends = addends;
|
|
|
-+
|
|
|
-+ head = &ldso;
|
|
|
-+ reloc_all(&ldso);
|
|
|
-+
|
|
|
-+ ldso.relocated = 0;
|
|
|
-+
|
|
|
-+ /* Call dynamic linker stage-3, __dls3, looking it up
|
|
|
-+ * symbolically as a barrier against moving the address
|
|
|
-+ * load across the above relocation processing. */
|
|
|
-+ struct symdef dls3_def = find_sym(&ldso, "__dls3", 0);
|
|
|
-+ if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp);
|
|
|
-+ else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp);
|
|
|
-+}
|
|
|
-+
|
|
|
-+/* Stage 3 of the dynamic linker is called with the dynamic linker/libc
|
|
|
-+ * fully functional. Its job is to load (if not already loaded) and
|
|
|
-+ * process dependencies and relocations for the main application and
|
|
|
-+ * transfer control to its entry point. */
|
|
|
-+
|
|
|
-+_Noreturn void __dls3(size_t *sp)
|
|
|
-+{
|
|
|
-+ static struct dso app, vdso;
|
|
|
-+ size_t aux[AUX_CNT], *auxv;
|
|
|
-+ size_t i;
|
|
|
-+ char *env_preload=0;
|
|
|
-+ size_t vdso_base;
|
|
|
-+ int argc = *sp;
|
|
|
-+ char **argv = (void *)(sp+1);
|
|
|
-+ char **argv_orig = argv;
|
|
|
-+ char **envp = argv+argc+1;
|
|
|
-+
|
|
|
-+ /* Find aux vector just past environ[] and use it to initialize
|
|
|
-+ * global data that may be needed before we can make syscalls. */
|
|
|
-+ __environ = envp;
|
|
|
-+ for (i=argc+1; argv[i]; i++);
|
|
|
-+ libc.auxv = auxv = (void *)(argv+i+1);
|
|
|
-+ decode_vec(auxv, aux, AUX_CNT);
|
|
|
-+ __hwcap = aux[AT_HWCAP];
|
|
|
-+ libc.page_size = aux[AT_PAGESZ];
|
|
|
-+ libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
|
|
|
-+ || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]);
|
|
|
-+
|
|
|
-+ /* Setup early thread pointer in builtin_tls for ldso/libc itself to
|
|
|
-+ * use during dynamic linking. If possible it will also serve as the
|
|
|
-+ * thread pointer at runtime. */
|
|
|
-+ libc.tls_size = sizeof builtin_tls;
|
|
|
-+ libc.tls_align = tls_align;
|
|
|
-+ if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {
|
|
|
-+ a_crash();
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Only trust user/env if kernel says we're not suid/sgid */
|
|
|
-+ if (!libc.secure) {
|
|
|
-+ env_path = getenv("LD_LIBRARY_PATH");
|
|
|
-+ env_preload = getenv("LD_PRELOAD");
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* If the main program was already loaded by the kernel,
|
|
|
-+ * AT_PHDR will point to some location other than the dynamic
|
|
|
-+ * linker's program headers. */
|
|
|
-+ if (aux[AT_PHDR] != (size_t)ldso.phdr) {
|
|
|
-+ size_t interp_off = 0;
|
|
|
-+ size_t tls_image = 0;
|
|
|
-+ /* Find load address of the main program, via AT_PHDR vs PT_PHDR. */
|
|
|
-+ Phdr *phdr = app.phdr = (void *)aux[AT_PHDR];
|
|
|
-+ app.phnum = aux[AT_PHNUM];
|
|
|
-+ app.phentsize = aux[AT_PHENT];
|
|
|
-+ for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) {
|
|
|
-+ if (phdr->p_type == PT_PHDR)
|
|
|
-+ app.base = (void *)(aux[AT_PHDR] - phdr->p_vaddr);
|
|
|
-+ else if (phdr->p_type == PT_INTERP)
|
|
|
-+ interp_off = (size_t)phdr->p_vaddr;
|
|
|
-+ else if (phdr->p_type == PT_TLS) {
|
|
|
-+ tls_image = phdr->p_vaddr;
|
|
|
-+ app.tls.len = phdr->p_filesz;
|
|
|
-+ app.tls.size = phdr->p_memsz;
|
|
|
-+ app.tls.align = phdr->p_align;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ if (DL_FDPIC) app.loadmap = app_loadmap;
|
|
|
-+ if (app.tls.size) app.tls.image = laddr(&app, tls_image);
|
|
|
-+ if (interp_off) ldso.name = laddr(&app, interp_off);
|
|
|
-+ if ((aux[0] & (1UL<<AT_EXECFN))
|
|
|
-+ && strncmp((char *)aux[AT_EXECFN], "/proc/", 6))
|
|
|
-+ app.name = (char *)aux[AT_EXECFN];
|
|
|
-+ else
|
|
|
-+ app.name = argv[0];
|
|
|
-+ kernel_mapped_dso(&app);
|
|
|
-+ } else {
|
|
|
-+ int fd;
|
|
|
-+ char *ldname = argv[0];
|
|
|
-+ size_t l = strlen(ldname);
|
|
|
-+ if (l >= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1;
|
|
|
-+ argv++;
|
|
|
-+ while (argv[0] && argv[0][0]=='-' && argv[0][1]=='-') {
|
|
|
-+ char *opt = argv[0]+2;
|
|
|
-+ *argv++ = (void *)-1;
|
|
|
-+ if (!*opt) {
|
|
|
-+ break;
|
|
|
-+ } else if (!memcmp(opt, "list", 5)) {
|
|
|
-+ ldd_mode = 1;
|
|
|
-+ } else if (!memcmp(opt, "library-path", 12)) {
|
|
|
-+ if (opt[12]=='=') env_path = opt+13;
|
|
|
-+ else if (opt[12]) *argv = 0;
|
|
|
-+ else if (*argv) env_path = *argv++;
|
|
|
-+ } else if (!memcmp(opt, "preload", 7)) {
|
|
|
-+ if (opt[7]=='=') env_preload = opt+8;
|
|
|
-+ else if (opt[7]) *argv = 0;
|
|
|
-+ else if (*argv) env_preload = *argv++;
|
|
|
-+ } else {
|
|
|
-+ argv[0] = 0;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ argv[-1] = (void *)(argc - (argv-argv_orig));
|
|
|
-+ if (!argv[0]) {
|
|
|
-+ dprintf(2, "musl libc (" LDSO_ARCH ")\n"
|
|
|
-+ "Version %s\n"
|
|
|
-+ "Dynamic Program Loader\n"
|
|
|
-+ "Usage: %s [options] [--] pathname%s\n",
|
|
|
-+ __libc_get_version(), ldname,
|
|
|
-+ ldd_mode ? "" : " [args]");
|
|
|
-+ _exit(1);
|
|
|
-+ }
|
|
|
-+ fd = open(argv[0], O_RDONLY);
|
|
|
-+ if (fd < 0) {
|
|
|
-+ dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno));
|
|
|
-+ _exit(1);
|
|
|
-+ }
|
|
|
-+ runtime = 1;
|
|
|
-+ Ehdr *ehdr = (void *)map_library(fd, &app);
|
|
|
-+ if (!ehdr) {
|
|
|
-+ dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]);
|
|
|
-+ _exit(1);
|
|
|
-+ }
|
|
|
-+ runtime = 0;
|
|
|
-+ close(fd);
|
|
|
-+ ldso.name = ldname;
|
|
|
-+ app.name = argv[0];
|
|
|
-+ aux[AT_ENTRY] = (size_t)laddr(&app, ehdr->e_entry);
|
|
|
-+ /* Find the name that would have been used for the dynamic
|
|
|
-+ * linker had ldd not taken its place. */
|
|
|
-+ if (ldd_mode) {
|
|
|
-+ for (i=0; i<app.phnum; i++) {
|
|
|
-+ if (app.phdr[i].p_type == PT_INTERP)
|
|
|
-+ ldso.name = laddr(&app, app.phdr[i].p_vaddr);
|
|
|
-+ }
|
|
|
-+ dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base);
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ if (app.tls.size) {
|
|
|
-+ libc.tls_head = tls_tail = &app.tls;
|
|
|
-+ app.tls_id = tls_cnt = 1;
|
|
|
-+#ifdef TLS_ABOVE_TP
|
|
|
-+ app.tls.offset = 0;
|
|
|
-+ tls_offset = app.tls.size
|
|
|
-+ + ( -((uintptr_t)app.tls.image + app.tls.size)
|
|
|
-+ & (app.tls.align-1) );
|
|
|
-+#else
|
|
|
-+ tls_offset = app.tls.offset = app.tls.size
|
|
|
-+ + ( -((uintptr_t)app.tls.image + app.tls.size)
|
|
|
-+ & (app.tls.align-1) );
|
|
|
-+#endif
|
|
|
-+ tls_align = MAXP2(tls_align, app.tls.align);
|
|
|
-+ }
|
|
|
-+ app.global = 1;
|
|
|
-+ decode_dyn(&app);
|
|
|
-+ if (DL_FDPIC) {
|
|
|
-+ makefuncdescs(&app);
|
|
|
-+ if (!app.loadmap) {
|
|
|
-+ app.loadmap = (void *)&app_dummy_loadmap;
|
|
|
-+ app.loadmap->nsegs = 1;
|
|
|
-+ app.loadmap->segs[0].addr = (size_t)app.map;
|
|
|
-+ app.loadmap->segs[0].p_vaddr = (size_t)app.map
|
|
|
-+ - (size_t)app.base;
|
|
|
-+ app.loadmap->segs[0].p_memsz = app.map_len;
|
|
|
-+ }
|
|
|
-+ argv[-3] = (void *)app.loadmap;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Attach to vdso, if provided by the kernel */
|
|
|
-+ if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR)) {
|
|
|
-+ Ehdr *ehdr = (void *)vdso_base;
|
|
|
-+ Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff);
|
|
|
-+ vdso.phnum = ehdr->e_phnum;
|
|
|
-+ vdso.phentsize = ehdr->e_phentsize;
|
|
|
-+ for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
|
|
|
-+ if (phdr->p_type == PT_DYNAMIC)
|
|
|
-+ vdso.dynv = (void *)(vdso_base + phdr->p_offset);
|
|
|
-+ if (phdr->p_type == PT_LOAD)
|
|
|
-+ vdso.base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);
|
|
|
-+ }
|
|
|
-+ vdso.name = "";
|
|
|
-+ vdso.shortname = "linux-gate.so.1";
|
|
|
-+ vdso.global = 1;
|
|
|
-+ vdso.relocated = 1;
|
|
|
-+ decode_dyn(&vdso);
|
|
|
-+ vdso.prev = &ldso;
|
|
|
-+ ldso.next = &vdso;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Initial dso chain consists only of the app. */
|
|
|
-+ head = tail = &app;
|
|
|
-+
|
|
|
-+ /* Donate unused parts of app and library mapping to malloc */
|
|
|
-+ reclaim_gaps(&app);
|
|
|
-+ reclaim_gaps(&ldso);
|
|
|
-+
|
|
|
-+ /* Load preload/needed libraries, add their symbols to the global
|
|
|
-+ * namespace, and perform all remaining relocations. */
|
|
|
-+ if (env_preload) load_preload(env_preload);
|
|
|
-+ load_deps(&app);
|
|
|
-+ make_global(&app);
|
|
|
-+
|
|
|
-+#ifndef DYNAMIC_IS_RO
|
|
|
-+ for (i=0; app.dynv[i]; i+=2)
|
|
|
-+ if (app.dynv[i]==DT_DEBUG)
|
|
|
-+ app.dynv[i+1] = (size_t)&debug;
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+ /* The main program must be relocated LAST since it may contin
|
|
|
-+ * copy relocations which depend on libraries' relocations. */
|
|
|
-+ reloc_all(app.next);
|
|
|
-+ reloc_all(&app);
|
|
|
-+
|
|
|
-+ update_tls_size();
|
|
|
-+ if (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) {
|
|
|
-+ void *initial_tls = calloc(libc.tls_size, 1);
|
|
|
-+ if (!initial_tls) {
|
|
|
-+ dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n",
|
|
|
-+ argv[0], libc.tls_size);
|
|
|
-+ _exit(127);
|
|
|
-+ }
|
|
|
-+ if (__init_tp(__copy_tls(initial_tls)) < 0) {
|
|
|
-+ a_crash();
|
|
|
-+ }
|
|
|
-+ } else {
|
|
|
-+ size_t tmp_tls_size = libc.tls_size;
|
|
|
-+ pthread_t self = __pthread_self();
|
|
|
-+ /* Temporarily set the tls size to the full size of
|
|
|
-+ * builtin_tls so that __copy_tls will use the same layout
|
|
|
-+ * as it did for before. Then check, just to be safe. */
|
|
|
-+ libc.tls_size = sizeof builtin_tls;
|
|
|
-+ if (__copy_tls((void*)builtin_tls) != self) a_crash();
|
|
|
-+ libc.tls_size = tmp_tls_size;
|
|
|
-+ }
|
|
|
-+ static_tls_cnt = tls_cnt;
|
|
|
-+
|
|
|
-+ if (ldso_fail) _exit(127);
|
|
|
-+ if (ldd_mode) _exit(0);
|
|
|
-+
|
|
|
-+ /* Switch to runtime mode: any further failures in the dynamic
|
|
|
-+ * linker are a reportable failure rather than a fatal startup
|
|
|
-+ * error. */
|
|
|
-+ runtime = 1;
|
|
|
-+
|
|
|
-+ debug.ver = 1;
|
|
|
-+ debug.bp = dl_debug_state;
|
|
|
-+ debug.head = head;
|
|
|
-+ debug.base = ldso.base;
|
|
|
-+ debug.state = 0;
|
|
|
-+ _dl_debug_state();
|
|
|
-+
|
|
|
-+ errno = 0;
|
|
|
-+
|
|
|
-+ CRTJMP((void *)aux[AT_ENTRY], argv-1);
|
|
|
-+ for(;;);
|
|
|
-+}
|
|
|
-+
|
|
|
-+void *dlopen(const char *file, int mode)
|
|
|
-+{
|
|
|
-+ struct dso *volatile p, *orig_tail, *next;
|
|
|
-+ struct tls_module *orig_tls_tail;
|
|
|
-+ size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;
|
|
|
-+ size_t i;
|
|
|
-+ int cs;
|
|
|
-+ jmp_buf jb;
|
|
|
-+
|
|
|
-+ if (!file) return head;
|
|
|
-+
|
|
|
-+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
|
|
|
-+ pthread_rwlock_wrlock(&lock);
|
|
|
-+ __inhibit_ptc();
|
|
|
-+
|
|
|
-+ p = 0;
|
|
|
-+ orig_tls_tail = tls_tail;
|
|
|
-+ orig_tls_cnt = tls_cnt;
|
|
|
-+ orig_tls_offset = tls_offset;
|
|
|
-+ orig_tls_align = tls_align;
|
|
|
-+ orig_tail = tail;
|
|
|
-+ noload = mode & RTLD_NOLOAD;
|
|
|
-+
|
|
|
-+ rtld_fail = &jb;
|
|
|
-+ if (setjmp(*rtld_fail)) {
|
|
|
-+ /* Clean up anything new that was (partially) loaded */
|
|
|
-+ if (p && p->deps) for (i=0; p->deps[i]; i++)
|
|
|
-+ if (p->deps[i]->global < 0)
|
|
|
-+ p->deps[i]->global = 0;
|
|
|
-+ for (p=orig_tail->next; p; p=next) {
|
|
|
-+ next = p->next;
|
|
|
-+ while (p->td_index) {
|
|
|
-+ void *tmp = p->td_index->next;
|
|
|
-+ free(p->td_index);
|
|
|
-+ p->td_index = tmp;
|
|
|
-+ }
|
|
|
-+ free(p->funcdescs);
|
|
|
-+ if (p->rpath != p->rpath_orig)
|
|
|
-+ free(p->rpath);
|
|
|
-+ free(p->deps);
|
|
|
-+ unmap_library(p);
|
|
|
-+ free(p);
|
|
|
-+ }
|
|
|
-+ if (!orig_tls_tail) libc.tls_head = 0;
|
|
|
-+ tls_tail = orig_tls_tail;
|
|
|
-+ tls_cnt = orig_tls_cnt;
|
|
|
-+ tls_offset = orig_tls_offset;
|
|
|
-+ tls_align = orig_tls_align;
|
|
|
-+ tail = orig_tail;
|
|
|
-+ tail->next = 0;
|
|
|
-+ p = 0;
|
|
|
-+ goto end;
|
|
|
-+ } else p = load_library(file, head);
|
|
|
-+
|
|
|
-+ if (!p) {
|
|
|
-+ error(noload ?
|
|
|
-+ "Library %s is not already loaded" :
|
|
|
-+ "Error loading shared library %s: %m",
|
|
|
-+ file);
|
|
|
-+ goto end;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* First load handling */
|
|
|
-+ if (!p->deps) {
|
|
|
-+ load_deps(p);
|
|
|
-+ if (p->deps) for (i=0; p->deps[i]; i++)
|
|
|
-+ if (!p->deps[i]->global)
|
|
|
-+ p->deps[i]->global = -1;
|
|
|
-+ if (!p->global) p->global = -1;
|
|
|
-+ reloc_all(p);
|
|
|
-+ if (p->deps) for (i=0; p->deps[i]; i++)
|
|
|
-+ if (p->deps[i]->global < 0)
|
|
|
-+ p->deps[i]->global = 0;
|
|
|
-+ if (p->global < 0) p->global = 0;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ if (mode & RTLD_GLOBAL) {
|
|
|
-+ if (p->deps) for (i=0; p->deps[i]; i++)
|
|
|
-+ p->deps[i]->global = 1;
|
|
|
-+ p->global = 1;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ update_tls_size();
|
|
|
-+ _dl_debug_state();
|
|
|
-+ orig_tail = tail;
|
|
|
-+end:
|
|
|
-+ __release_ptc();
|
|
|
-+ if (p) gencnt++;
|
|
|
-+ pthread_rwlock_unlock(&lock);
|
|
|
-+ if (p) do_init_fini(orig_tail);
|
|
|
-+ pthread_setcancelstate(cs, 0);
|
|
|
-+ return p;
|
|
|
-+}
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+int __dl_invalid_handle(void *h)
|
|
|
-+{
|
|
|
-+ struct dso *p;
|
|
|
-+ for (p=head; p; p=p->next) if (h==p) return 0;
|
|
|
-+ error("Invalid library handle %p", (void *)h);
|
|
|
-+ return 1;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static void *addr2dso(size_t a)
|
|
|
-+{
|
|
|
-+ struct dso *p;
|
|
|
-+ size_t i;
|
|
|
-+ if (DL_FDPIC) for (p=head; p; p=p->next) {
|
|
|
-+ i = count_syms(p);
|
|
|
-+ if (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs))
|
|
|
-+ return p;
|
|
|
-+ }
|
|
|
-+ for (p=head; p; p=p->next) {
|
|
|
-+ if (DL_FDPIC && p->loadmap) {
|
|
|
-+ for (i=0; i<p->loadmap->nsegs; i++) {
|
|
|
-+ if (a-p->loadmap->segs[i].p_vaddr
|
|
|
-+ < p->loadmap->segs[i].p_memsz)
|
|
|
-+ return p;
|
|
|
-+ }
|
|
|
-+ } else {
|
|
|
-+ if (a-(size_t)p->map < p->map_len)
|
|
|
-+ return p;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+void *__tls_get_addr(size_t *);
|
|
|
-+
|
|
|
-+static void *do_dlsym(struct dso *p, const char *s, void *ra)
|
|
|
-+{
|
|
|
-+ size_t i;
|
|
|
-+ uint32_t h = 0, gh = 0, *ght;
|
|
|
-+ Sym *sym;
|
|
|
-+ if (p == head || p == RTLD_DEFAULT || p == RTLD_NEXT) {
|
|
|
-+ if (p == RTLD_DEFAULT) {
|
|
|
-+ p = head;
|
|
|
-+ } else if (p == RTLD_NEXT) {
|
|
|
-+ p = addr2dso((size_t)ra);
|
|
|
-+ if (!p) p=head;
|
|
|
-+ p = p->next;
|
|
|
-+ }
|
|
|
-+ struct symdef def = find_sym(p, s, 0);
|
|
|
-+ if (!def.sym) goto failed;
|
|
|
-+ if ((def.sym->st_info&0xf) == STT_TLS)
|
|
|
-+ return __tls_get_addr((size_t []){def.dso->tls_id, def.sym->st_value});
|
|
|
-+ if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC)
|
|
|
-+ return def.dso->funcdescs + (def.sym - def.dso->syms);
|
|
|
-+ return laddr(def.dso, def.sym->st_value);
|
|
|
-+ }
|
|
|
-+ if (__dl_invalid_handle(p))
|
|
|
-+ return 0;
|
|
|
-+ if ((ght = p->ghashtab)) {
|
|
|
-+ gh = gnu_hash(s);
|
|
|
-+ sym = gnu_lookup(gh, ght, p, s);
|
|
|
-+ } else {
|
|
|
-+ h = sysv_hash(s);
|
|
|
-+ sym = sysv_lookup(s, h, p);
|
|
|
-+ }
|
|
|
-+ if (sym && (sym->st_info&0xf) == STT_TLS)
|
|
|
-+ return __tls_get_addr((size_t []){p->tls_id, sym->st_value});
|
|
|
-+ if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC)
|
|
|
-+ return p->funcdescs + (sym - p->syms);
|
|
|
-+ if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
|
|
|
-+ return laddr(p, sym->st_value);
|
|
|
-+ if (p->deps) for (i=0; p->deps[i]; i++) {
|
|
|
-+ if ((ght = p->deps[i]->ghashtab)) {
|
|
|
-+ if (!gh) gh = gnu_hash(s);
|
|
|
-+ sym = gnu_lookup(gh, ght, p->deps[i], s);
|
|
|
-+ } else {
|
|
|
-+ if (!h) h = sysv_hash(s);
|
|
|
-+ sym = sysv_lookup(s, h, p->deps[i]);
|
|
|
-+ }
|
|
|
-+ if (sym && (sym->st_info&0xf) == STT_TLS)
|
|
|
-+ return __tls_get_addr((size_t []){p->deps[i]->tls_id, sym->st_value});
|
|
|
-+ if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC)
|
|
|
-+ return p->deps[i]->funcdescs + (sym - p->deps[i]->syms);
|
|
|
-+ if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
|
|
|
-+ return laddr(p->deps[i], sym->st_value);
|
|
|
-+ }
|
|
|
-+failed:
|
|
|
-+ error("Symbol not found: %s", s);
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+int dladdr(const void *addr, Dl_info *info)
|
|
|
-+{
|
|
|
-+ struct dso *p;
|
|
|
-+ Sym *sym, *bestsym;
|
|
|
-+ uint32_t nsym;
|
|
|
-+ char *strings;
|
|
|
-+ void *best = 0;
|
|
|
-+
|
|
|
-+ pthread_rwlock_rdlock(&lock);
|
|
|
-+ p = addr2dso((size_t)addr);
|
|
|
-+ pthread_rwlock_unlock(&lock);
|
|
|
-+
|
|
|
-+ if (!p) return 0;
|
|
|
-+
|
|
|
-+ sym = p->syms;
|
|
|
-+ strings = p->strings;
|
|
|
-+ nsym = count_syms(p);
|
|
|
-+
|
|
|
-+ if (DL_FDPIC) {
|
|
|
-+ size_t idx = ((size_t)addr-(size_t)p->funcdescs)
|
|
|
-+ / sizeof(*p->funcdescs);
|
|
|
-+ if (idx < nsym && (sym[idx].st_info&0xf) == STT_FUNC) {
|
|
|
-+ best = p->funcdescs + idx;
|
|
|
-+ bestsym = sym + idx;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ if (!best) for (; nsym; nsym--, sym++) {
|
|
|
-+ if (sym->st_value
|
|
|
-+ && (1<<(sym->st_info&0xf) & OK_TYPES)
|
|
|
-+ && (1<<(sym->st_info>>4) & OK_BINDS)) {
|
|
|
-+ void *symaddr = laddr(p, sym->st_value);
|
|
|
-+ if (symaddr > addr || symaddr < best)
|
|
|
-+ continue;
|
|
|
-+ best = symaddr;
|
|
|
-+ bestsym = sym;
|
|
|
-+ if (addr == symaddr)
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ if (!best) return 0;
|
|
|
-+
|
|
|
-+ if (DL_FDPIC && (bestsym->st_info&0xf) == STT_FUNC)
|
|
|
-+ best = p->funcdescs + (bestsym - p->syms);
|
|
|
-+
|
|
|
-+ info->dli_fname = p->name;
|
|
|
-+ info->dli_fbase = p->base;
|
|
|
-+ info->dli_sname = strings + bestsym->st_name;
|
|
|
-+ info->dli_saddr = best;
|
|
|
-+
|
|
|
-+ return 1;
|
|
|
-+}
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
|
|
|
-+{
|
|
|
-+ void *res;
|
|
|
-+ pthread_rwlock_rdlock(&lock);
|
|
|
-+ res = do_dlsym(p, s, ra);
|
|
|
-+ pthread_rwlock_unlock(&lock);
|
|
|
-+ return res;
|
|
|
-+}
|
|
|
-+
|
|
|
-+int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
|
|
|
-+{
|
|
|
-+ struct dso *current;
|
|
|
-+ struct dl_phdr_info info;
|
|
|
-+ int ret = 0;
|
|
|
-+ for(current = head; current;) {
|
|
|
-+ info.dlpi_addr = (uintptr_t)current->base;
|
|
|
-+ info.dlpi_name = current->name;
|
|
|
-+ info.dlpi_phdr = current->phdr;
|
|
|
-+ info.dlpi_phnum = current->phnum;
|
|
|
-+ info.dlpi_adds = gencnt;
|
|
|
-+ info.dlpi_subs = 0;
|
|
|
-+ info.dlpi_tls_modid = current->tls_id;
|
|
|
-+ info.dlpi_tls_data = current->tls.image;
|
|
|
-+
|
|
|
-+ ret = (callback)(&info, sizeof (info), data);
|
|
|
-+
|
|
|
-+ if (ret != 0) break;
|
|
|
-+
|
|
|
-+ pthread_rwlock_rdlock(&lock);
|
|
|
-+ current = current->next;
|
|
|
-+ pthread_rwlock_unlock(&lock);
|
|
|
-+ }
|
|
|
-+ return ret;
|
|
|
-+}
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+void __dl_vseterr(const char *, va_list);
|
|
|
-+
|
|
|
-+static void error(const char *fmt, ...)
|
|
|
-+{
|
|
|
-+ va_list ap;
|
|
|
-+ va_start(ap, fmt);
|
|
|
-+ if (!runtime) {
|
|
|
-+ vdprintf(2, fmt, ap);
|
|
|
-+ dprintf(2, "\n");
|
|
|
-+ ldso_fail = 1;
|
|
|
-+ va_end(ap);
|
|
|
-+ return;
|
|
|
-+ }
|
|
|
-+ __dl_vseterr(fmt, ap);
|
|
|
-+ va_end(ap);
|
|
|
-+}
|
|
|
---- a/src/env/__init_tls.c
|
|
|
-+++ b/src/env/__init_tls.c
|
|
|
-@@ -8,9 +8,6 @@
|
|
|
- #include "atomic.h"
|
|
|
- #include "syscall.h"
|
|
|
-
|
|
|
--#ifndef SHARED
|
|
|
--static
|
|
|
--#endif
|
|
|
- int __init_tp(void *p)
|
|
|
- {
|
|
|
- pthread_t td = p;
|
|
|
-@@ -24,8 +21,6 @@ int __init_tp(void *p)
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
--#ifndef SHARED
|
|
|
--
|
|
|
- static struct builtin_tls {
|
|
|
- char c;
|
|
|
- struct pthread pt;
|
|
|
-@@ -33,33 +28,40 @@ static struct builtin_tls {
|
|
|
- } builtin_tls[1];
|
|
|
- #define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
|
|
|
-
|
|
|
--struct tls_image {
|
|
|
-- void *image;
|
|
|
-- size_t len, size, align;
|
|
|
--} __static_tls;
|
|
|
--
|
|
|
--#define T __static_tls
|
|
|
-+static struct tls_module main_tls;
|
|
|
-
|
|
|
- void *__copy_tls(unsigned char *mem)
|
|
|
- {
|
|
|
- pthread_t td;
|
|
|
-- if (!T.image) return mem;
|
|
|
-- void **dtv = (void *)mem;
|
|
|
-- dtv[0] = (void *)1;
|
|
|
-+ struct tls_module *p;
|
|
|
-+ size_t i;
|
|
|
-+ void **dtv;
|
|
|
-+
|
|
|
- #ifdef TLS_ABOVE_TP
|
|
|
-- mem += sizeof(void *) * 2;
|
|
|
-- mem += -((uintptr_t)mem + sizeof(struct pthread)) & (T.align-1);
|
|
|
-+ dtv = (void **)(mem + libc.tls_size) - (libc.tls_cnt + 1);
|
|
|
-+
|
|
|
-+ mem += -((uintptr_t)mem + sizeof(struct pthread)) & (libc.tls_align-1);
|
|
|
- td = (pthread_t)mem;
|
|
|
- mem += sizeof(struct pthread);
|
|
|
-+
|
|
|
-+ for (i=1, p=libc.tls_head; p; i++, p=p->next) {
|
|
|
-+ dtv[i] = mem + p->offset;
|
|
|
-+ memcpy(dtv[i], p->image, p->len);
|
|
|
-+ }
|
|
|
- #else
|
|
|
-+ dtv = (void **)mem;
|
|
|
-+
|
|
|
- mem += libc.tls_size - sizeof(struct pthread);
|
|
|
-- mem -= (uintptr_t)mem & (T.align-1);
|
|
|
-+ mem -= (uintptr_t)mem & (libc.tls_align-1);
|
|
|
- td = (pthread_t)mem;
|
|
|
-- mem -= T.size;
|
|
|
-+
|
|
|
-+ for (i=1, p=libc.tls_head; p; i++, p=p->next) {
|
|
|
-+ dtv[i] = mem - p->offset;
|
|
|
-+ memcpy(dtv[i], p->image, p->len);
|
|
|
-+ }
|
|
|
- #endif
|
|
|
-+ dtv[0] = (void *)libc.tls_cnt;
|
|
|
- td->dtv = td->dtv_copy = dtv;
|
|
|
-- dtv[1] = mem;
|
|
|
-- memcpy(mem, T.image, T.len);
|
|
|
- return td;
|
|
|
- }
|
|
|
-
|
|
|
-@@ -69,7 +71,7 @@ typedef Elf32_Phdr Phdr;
|
|
|
- typedef Elf64_Phdr Phdr;
|
|
|
- #endif
|
|
|
-
|
|
|
--void __init_tls(size_t *aux)
|
|
|
-+static void static_init_tls(size_t *aux)
|
|
|
- {
|
|
|
- unsigned char *p;
|
|
|
- size_t n;
|
|
|
-@@ -86,16 +88,24 @@ void __init_tls(size_t *aux)
|
|
|
- }
|
|
|
-
|
|
|
- if (tls_phdr) {
|
|
|
-- T.image = (void *)(base + tls_phdr->p_vaddr);
|
|
|
-- T.len = tls_phdr->p_filesz;
|
|
|
-- T.size = tls_phdr->p_memsz;
|
|
|
-- T.align = tls_phdr->p_align;
|
|
|
-+ main_tls.image = (void *)(base + tls_phdr->p_vaddr);
|
|
|
-+ main_tls.len = tls_phdr->p_filesz;
|
|
|
-+ main_tls.size = tls_phdr->p_memsz;
|
|
|
-+ main_tls.align = tls_phdr->p_align;
|
|
|
-+ libc.tls_cnt = 1;
|
|
|
-+ libc.tls_head = &main_tls;
|
|
|
- }
|
|
|
-
|
|
|
-- T.size += (-T.size - (uintptr_t)T.image) & (T.align-1);
|
|
|
-- if (T.align < MIN_TLS_ALIGN) T.align = MIN_TLS_ALIGN;
|
|
|
-+ main_tls.size += (-main_tls.size - (uintptr_t)main_tls.image)
|
|
|
-+ & (main_tls.align-1);
|
|
|
-+ if (main_tls.align < MIN_TLS_ALIGN) main_tls.align = MIN_TLS_ALIGN;
|
|
|
-+#ifndef TLS_ABOVE_TP
|
|
|
-+ main_tls.offset = main_tls.size;
|
|
|
-+#endif
|
|
|
-
|
|
|
-- libc.tls_size = 2*sizeof(void *)+T.size+T.align+sizeof(struct pthread)
|
|
|
-+ libc.tls_align = main_tls.align;
|
|
|
-+ libc.tls_size = 2*sizeof(void *) + sizeof(struct pthread)
|
|
|
-+ + main_tls.size + main_tls.align
|
|
|
- + MIN_TLS_ALIGN-1 & -MIN_TLS_ALIGN;
|
|
|
-
|
|
|
- if (libc.tls_size > sizeof builtin_tls) {
|
|
|
-@@ -117,6 +127,5 @@ void __init_tls(size_t *aux)
|
|
|
- if (__init_tp(__copy_tls(mem)) < 0)
|
|
|
- a_crash();
|
|
|
- }
|
|
|
--#else
|
|
|
--void __init_tls(size_t *auxv) { }
|
|
|
--#endif
|
|
|
-+
|
|
|
-+weak_alias(static_init_tls, __init_tls);
|
|
|
---- a/src/env/__libc_start_main.c
|
|
|
-+++ b/src/env/__libc_start_main.c
|
|
|
-@@ -8,21 +8,17 @@
|
|
|
-
|
|
|
- void __init_tls(size_t *);
|
|
|
-
|
|
|
--#ifndef SHARED
|
|
|
--static void dummy() {}
|
|
|
-+static void dummy(void) {}
|
|
|
- weak_alias(dummy, _init);
|
|
|
--extern void (*const __init_array_start)() __attribute__((weak));
|
|
|
--extern void (*const __init_array_end)() __attribute__((weak));
|
|
|
--#endif
|
|
|
-+
|
|
|
-+__attribute__((__weak__, __visibility__("hidden")))
|
|
|
-+extern void (*const __init_array_start)(void), (*const __init_array_end)(void);
|
|
|
-
|
|
|
- static void dummy1(void *p) {}
|
|
|
- weak_alias(dummy1, __init_ssp);
|
|
|
-
|
|
|
- #define AUX_CNT 38
|
|
|
-
|
|
|
--#ifndef SHARED
|
|
|
--static
|
|
|
--#endif
|
|
|
- void __init_libc(char **envp, char *pn)
|
|
|
- {
|
|
|
- size_t i, *auxv, aux[AUX_CNT] = { 0 };
|
|
|
-@@ -57,20 +53,22 @@ void __init_libc(char **envp, char *pn)
|
|
|
- libc.secure = 1;
|
|
|
- }
|
|
|
-
|
|
|
--int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv)
|
|
|
-+static void libc_start_init(void)
|
|
|
- {
|
|
|
-- char **envp = argv+argc+1;
|
|
|
--
|
|
|
--#ifndef SHARED
|
|
|
-- __init_libc(envp, argv[0]);
|
|
|
- _init();
|
|
|
- uintptr_t a = (uintptr_t)&__init_array_start;
|
|
|
- for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)()))
|
|
|
- (*(void (**)())a)();
|
|
|
--#else
|
|
|
-- void __libc_start_init(void);
|
|
|
-+}
|
|
|
-+
|
|
|
-+weak_alias(libc_start_init, __libc_start_init);
|
|
|
-+
|
|
|
-+int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv)
|
|
|
-+{
|
|
|
-+ char **envp = argv+argc+1;
|
|
|
-+
|
|
|
-+ __init_libc(envp, argv[0]);
|
|
|
- __libc_start_init();
|
|
|
--#endif
|
|
|
-
|
|
|
- /* Pass control to the application */
|
|
|
- exit(main(argc, argv, envp));
|
|
|
---- a/src/env/__reset_tls.c
|
|
|
-+++ b/src/env/__reset_tls.c
|
|
|
-@@ -1,21 +1,16 @@
|
|
|
--#ifndef SHARED
|
|
|
--
|
|
|
- #include <string.h>
|
|
|
- #include "pthread_impl.h"
|
|
|
--
|
|
|
--extern struct tls_image {
|
|
|
-- void *image;
|
|
|
-- size_t len, size, align;
|
|
|
--} __static_tls;
|
|
|
--
|
|
|
--#define T __static_tls
|
|
|
-+#include "libc.h"
|
|
|
-
|
|
|
- void __reset_tls()
|
|
|
- {
|
|
|
-- if (!T.size) return;
|
|
|
- pthread_t self = __pthread_self();
|
|
|
-- memcpy(self->dtv[1], T.image, T.len);
|
|
|
-- memset((char *)self->dtv[1]+T.len, 0, T.size-T.len);
|
|
|
-+ struct tls_module *p;
|
|
|
-+ size_t i, n = (size_t)self->dtv[0];
|
|
|
-+ if (n) for (p=libc.tls_head, i=1; i<=n; i++, p=p->next) {
|
|
|
-+ if (!self->dtv[i]) continue;
|
|
|
-+ memcpy(self->dtv[i], p->image, p->len);
|
|
|
-+ memset((char *)self->dtv[i]+p->len, 0,
|
|
|
-+ p->size - p->len);
|
|
|
-+ }
|
|
|
- }
|
|
|
--
|
|
|
--#endif
|
|
|
---- a/src/env/__stack_chk_fail.c
|
|
|
-+++ b/src/env/__stack_chk_fail.c
|
|
|
-@@ -17,16 +17,7 @@ void __stack_chk_fail(void)
|
|
|
- a_crash();
|
|
|
- }
|
|
|
-
|
|
|
--#ifdef SHARED
|
|
|
--
|
|
|
- __attribute__((__visibility__("hidden")))
|
|
|
--void __stack_chk_fail_local(void)
|
|
|
--{
|
|
|
-- a_crash();
|
|
|
--}
|
|
|
--
|
|
|
--#else
|
|
|
-+void __stack_chk_fail_local(void);
|
|
|
-
|
|
|
- weak_alias(__stack_chk_fail, __stack_chk_fail_local);
|
|
|
--
|
|
|
--#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/src/exit/arm/__aeabi_atexit.c
|
|
|
-@@ -0,0 +1,6 @@
|
|
|
-+int __cxa_atexit(void (*func)(void *), void *arg, void *dso);
|
|
|
-+
|
|
|
-+int __aeabi_atexit (void *obj, void (*func) (void *), void *d)
|
|
|
-+{
|
|
|
-+ return __cxa_atexit (func, obj, d);
|
|
|
-+}
|
|
|
---- a/src/exit/exit.c
|
|
|
-+++ b/src/exit/exit.c
|
|
|
-@@ -10,25 +10,25 @@ static void dummy()
|
|
|
- * as a consequence of linking either __toread.c or __towrite.c. */
|
|
|
- weak_alias(dummy, __funcs_on_exit);
|
|
|
- weak_alias(dummy, __stdio_exit);
|
|
|
--
|
|
|
--#ifndef SHARED
|
|
|
- weak_alias(dummy, _fini);
|
|
|
--extern void (*const __fini_array_start)() __attribute__((weak));
|
|
|
--extern void (*const __fini_array_end)() __attribute__((weak));
|
|
|
--#endif
|
|
|
-
|
|
|
--_Noreturn void exit(int code)
|
|
|
--{
|
|
|
-- __funcs_on_exit();
|
|
|
-+__attribute__((__weak__, __visibility__("hidden")))
|
|
|
-+extern void (*const __fini_array_start)(void), (*const __fini_array_end)(void);
|
|
|
-
|
|
|
--#ifndef SHARED
|
|
|
-+static void libc_exit_fini(void)
|
|
|
-+{
|
|
|
- uintptr_t a = (uintptr_t)&__fini_array_end;
|
|
|
- for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)()))
|
|
|
- (*(void (**)())(a-sizeof(void(*)())))();
|
|
|
- _fini();
|
|
|
--#endif
|
|
|
-+}
|
|
|
-
|
|
|
-- __stdio_exit();
|
|
|
-+weak_alias(libc_exit_fini, __libc_exit_fini);
|
|
|
-
|
|
|
-+_Noreturn void exit(int code)
|
|
|
-+{
|
|
|
-+ __funcs_on_exit();
|
|
|
-+ __libc_exit_fini();
|
|
|
-+ __stdio_exit();
|
|
|
- _Exit(code);
|
|
|
- }
|
|
|
---- /dev/null
|
|
|
-+++ b/src/fenv/arm/fenv-hf.S
|
|
|
-@@ -0,0 +1,69 @@
|
|
|
-+#if __ARM_PCS_VFP
|
|
|
-+
|
|
|
-+.syntax unified
|
|
|
-+.fpu vfp
|
|
|
-+
|
|
|
-+.global fegetround
|
|
|
-+.type fegetround,%function
|
|
|
-+fegetround:
|
|
|
-+ fmrx r0, fpscr
|
|
|
-+ and r0, r0, #0xc00000
|
|
|
-+ bx lr
|
|
|
-+
|
|
|
-+.global __fesetround
|
|
|
-+.type __fesetround,%function
|
|
|
-+__fesetround:
|
|
|
-+ fmrx r3, fpscr
|
|
|
-+ bic r3, r3, #0xc00000
|
|
|
-+ orr r3, r3, r0
|
|
|
-+ fmxr fpscr, r3
|
|
|
-+ mov r0, #0
|
|
|
-+ bx lr
|
|
|
-+
|
|
|
-+.global fetestexcept
|
|
|
-+.type fetestexcept,%function
|
|
|
-+fetestexcept:
|
|
|
-+ and r0, r0, #0x1f
|
|
|
-+ fmrx r3, fpscr
|
|
|
-+ and r0, r0, r3
|
|
|
-+ bx lr
|
|
|
-+
|
|
|
-+.global feclearexcept
|
|
|
-+.type feclearexcept,%function
|
|
|
-+feclearexcept:
|
|
|
-+ and r0, r0, #0x1f
|
|
|
-+ fmrx r3, fpscr
|
|
|
-+ bic r3, r3, r0
|
|
|
-+ fmxr fpscr, r3
|
|
|
-+ mov r0, #0
|
|
|
-+ bx lr
|
|
|
-+
|
|
|
-+.global feraiseexcept
|
|
|
-+.type feraiseexcept,%function
|
|
|
-+feraiseexcept:
|
|
|
-+ and r0, r0, #0x1f
|
|
|
-+ fmrx r3, fpscr
|
|
|
-+ orr r3, r3, r0
|
|
|
-+ fmxr fpscr, r3
|
|
|
-+ mov r0, #0
|
|
|
-+ bx lr
|
|
|
-+
|
|
|
-+.global fegetenv
|
|
|
-+.type fegetenv,%function
|
|
|
-+fegetenv:
|
|
|
-+ fmrx r3, fpscr
|
|
|
-+ str r3, [r0]
|
|
|
-+ mov r0, #0
|
|
|
-+ bx lr
|
|
|
-+
|
|
|
-+.global fesetenv
|
|
|
-+.type fesetenv,%function
|
|
|
-+fesetenv:
|
|
|
-+ cmn r0, #1
|
|
|
-+ moveq r3, #0
|
|
|
-+ ldrne r3, [r0]
|
|
|
-+ fmxr fpscr, r3
|
|
|
-+ mov r0, #0
|
|
|
-+ bx lr
|
|
|
-+
|
|
|
-+#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/src/fenv/arm/fenv.c
|
|
|
-@@ -0,0 +1,3 @@
|
|
|
-+#if !__ARM_PCS_VFP
|
|
|
-+#include "../fenv.c"
|
|
|
-+#endif
|
|
|
---- a/src/fenv/armebhf/fenv.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../armhf/fenv.s
|
|
|
---- a/src/fenv/armhf/fenv.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,64 +0,0 @@
|
|
|
--.fpu vfp
|
|
|
--
|
|
|
--.global fegetround
|
|
|
--.type fegetround,%function
|
|
|
--fegetround:
|
|
|
-- mrc p10, 7, r0, cr1, cr0, 0
|
|
|
-- and r0, r0, #0xc00000
|
|
|
-- bx lr
|
|
|
--
|
|
|
--.global __fesetround
|
|
|
--.type __fesetround,%function
|
|
|
--__fesetround:
|
|
|
-- mrc p10, 7, r3, cr1, cr0, 0
|
|
|
-- bic r3, r3, #0xc00000
|
|
|
-- orr r3, r3, r0
|
|
|
-- mcr p10, 7, r3, cr1, cr0, 0
|
|
|
-- mov r0, #0
|
|
|
-- bx lr
|
|
|
--
|
|
|
--.global fetestexcept
|
|
|
--.type fetestexcept,%function
|
|
|
--fetestexcept:
|
|
|
-- and r0, r0, #0x1f
|
|
|
-- mrc p10, 7, r3, cr1, cr0, 0
|
|
|
-- and r0, r0, r3
|
|
|
-- bx lr
|
|
|
--
|
|
|
--.global feclearexcept
|
|
|
--.type feclearexcept,%function
|
|
|
--feclearexcept:
|
|
|
-- and r0, r0, #0x1f
|
|
|
-- mrc p10, 7, r3, cr1, cr0, 0
|
|
|
-- bic r3, r3, r0
|
|
|
-- mcr p10, 7, r3, cr1, cr0, 0
|
|
|
-- mov r0, #0
|
|
|
-- bx lr
|
|
|
--
|
|
|
--.global feraiseexcept
|
|
|
--.type feraiseexcept,%function
|
|
|
--feraiseexcept:
|
|
|
-- and r0, r0, #0x1f
|
|
|
-- mrc p10, 7, r3, cr1, cr0, 0
|
|
|
-- orr r3, r3, r0
|
|
|
-- mcr p10, 7, r3, cr1, cr0, 0
|
|
|
-- mov r0, #0
|
|
|
-- bx lr
|
|
|
--
|
|
|
--.global fegetenv
|
|
|
--.type fegetenv,%function
|
|
|
--fegetenv:
|
|
|
-- mrc p10, 7, r3, cr1, cr0, 0
|
|
|
-- str r3, [r0]
|
|
|
-- mov r0, #0
|
|
|
-- bx lr
|
|
|
--
|
|
|
--.global fesetenv
|
|
|
--.type fesetenv,%function
|
|
|
--fesetenv:
|
|
|
-- cmn r0, #1
|
|
|
-- moveq r3, #0
|
|
|
-- ldrne r3, [r0]
|
|
|
-- mcr p10, 7, r3, cr1, cr0, 0
|
|
|
-- mov r0, #0
|
|
|
-- bx lr
|
|
|
---- a/src/fenv/armhf/fenv.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--fenv.s
|
|
|
---- a/src/fenv/mips-sf/fenv.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../fenv.c
|
|
|
---- /dev/null
|
|
|
-+++ b/src/fenv/mips/fenv-sf.c
|
|
|
-@@ -0,0 +1,3 @@
|
|
|
-+#ifdef __mips_soft_float
|
|
|
-+#include "../fenv.c"
|
|
|
-+#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/src/fenv/mips/fenv.S
|
|
|
-@@ -0,0 +1,71 @@
|
|
|
-+#ifndef __mips_soft_float
|
|
|
-+
|
|
|
-+.set noreorder
|
|
|
-+
|
|
|
-+.global feclearexcept
|
|
|
-+.type feclearexcept,@function
|
|
|
-+feclearexcept:
|
|
|
-+ and $4, $4, 0x7c
|
|
|
-+ cfc1 $5, $31
|
|
|
-+ or $5, $5, $4
|
|
|
-+ xor $5, $5, $4
|
|
|
-+ ctc1 $5, $31
|
|
|
-+ jr $ra
|
|
|
-+ li $2, 0
|
|
|
-+
|
|
|
-+.global feraiseexcept
|
|
|
-+.type feraiseexcept,@function
|
|
|
-+feraiseexcept:
|
|
|
-+ and $4, $4, 0x7c
|
|
|
-+ cfc1 $5, $31
|
|
|
-+ or $5, $5, $4
|
|
|
-+ ctc1 $5, $31
|
|
|
-+ jr $ra
|
|
|
-+ li $2, 0
|
|
|
-+
|
|
|
-+.global fetestexcept
|
|
|
-+.type fetestexcept,@function
|
|
|
-+fetestexcept:
|
|
|
-+ and $4, $4, 0x7c
|
|
|
-+ cfc1 $2, $31
|
|
|
-+ jr $ra
|
|
|
-+ and $2, $2, $4
|
|
|
-+
|
|
|
-+.global fegetround
|
|
|
-+.type fegetround,@function
|
|
|
-+fegetround:
|
|
|
-+ cfc1 $2, $31
|
|
|
-+ jr $ra
|
|
|
-+ andi $2, $2, 3
|
|
|
-+
|
|
|
-+.global __fesetround
|
|
|
-+.type __fesetround,@function
|
|
|
-+__fesetround:
|
|
|
-+ cfc1 $5, $31
|
|
|
-+ li $6, -4
|
|
|
-+ and $5, $5, $6
|
|
|
-+ or $5, $5, $4
|
|
|
-+ ctc1 $5, $31
|
|
|
-+ jr $ra
|
|
|
-+ li $2, 0
|
|
|
-+
|
|
|
-+.global fegetenv
|
|
|
-+.type fegetenv,@function
|
|
|
-+fegetenv:
|
|
|
-+ cfc1 $5, $31
|
|
|
-+ sw $5, 0($4)
|
|
|
-+ jr $ra
|
|
|
-+ li $2, 0
|
|
|
-+
|
|
|
-+.global fesetenv
|
|
|
-+.type fesetenv,@function
|
|
|
-+fesetenv:
|
|
|
-+ addiu $5, $4, 1
|
|
|
-+ beq $5, $0, 1f
|
|
|
-+ nop
|
|
|
-+ lw $5, 0($4)
|
|
|
-+1: ctc1 $5, $31
|
|
|
-+ jr $ra
|
|
|
-+ li $2, 0
|
|
|
-+
|
|
|
-+#endif
|
|
|
---- a/src/fenv/mips/fenv.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,67 +0,0 @@
|
|
|
--.set noreorder
|
|
|
--
|
|
|
--.global feclearexcept
|
|
|
--.type feclearexcept,@function
|
|
|
--feclearexcept:
|
|
|
-- and $4, $4, 0x7c
|
|
|
-- cfc1 $5, $31
|
|
|
-- or $5, $5, $4
|
|
|
-- xor $5, $5, $4
|
|
|
-- ctc1 $5, $31
|
|
|
-- jr $ra
|
|
|
-- li $2, 0
|
|
|
--
|
|
|
--.global feraiseexcept
|
|
|
--.type feraiseexcept,@function
|
|
|
--feraiseexcept:
|
|
|
-- and $4, $4, 0x7c
|
|
|
-- cfc1 $5, $31
|
|
|
-- or $5, $5, $4
|
|
|
-- ctc1 $5, $31
|
|
|
-- jr $ra
|
|
|
-- li $2, 0
|
|
|
--
|
|
|
--.global fetestexcept
|
|
|
--.type fetestexcept,@function
|
|
|
--fetestexcept:
|
|
|
-- and $4, $4, 0x7c
|
|
|
-- cfc1 $2, $31
|
|
|
-- jr $ra
|
|
|
-- and $2, $2, $4
|
|
|
--
|
|
|
--.global fegetround
|
|
|
--.type fegetround,@function
|
|
|
--fegetround:
|
|
|
-- cfc1 $2, $31
|
|
|
-- jr $ra
|
|
|
-- andi $2, $2, 3
|
|
|
--
|
|
|
--.global __fesetround
|
|
|
--.type __fesetround,@function
|
|
|
--__fesetround:
|
|
|
-- cfc1 $5, $31
|
|
|
-- li $6, -4
|
|
|
-- and $5, $5, $6
|
|
|
-- or $5, $5, $4
|
|
|
-- ctc1 $5, $31
|
|
|
-- jr $ra
|
|
|
-- li $2, 0
|
|
|
--
|
|
|
--.global fegetenv
|
|
|
--.type fegetenv,@function
|
|
|
--fegetenv:
|
|
|
-- cfc1 $5, $31
|
|
|
-- sw $5, 0($4)
|
|
|
-- jr $ra
|
|
|
-- li $2, 0
|
|
|
--
|
|
|
--.global fesetenv
|
|
|
--.type fesetenv,@function
|
|
|
--fesetenv:
|
|
|
-- addiu $5, $4, 1
|
|
|
-- beq $5, $0, 1f
|
|
|
-- nop
|
|
|
-- lw $5, 0($4)
|
|
|
--1: ctc1 $5, $31
|
|
|
-- jr $ra
|
|
|
-- li $2, 0
|
|
|
---- a/src/fenv/mipsel-sf/fenv.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../fenv.c
|
|
|
---- a/src/fenv/sh-nofpu/fenv.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../fenv.c
|
|
|
---- /dev/null
|
|
|
-+++ b/src/fenv/sh/fenv-nofpu.c
|
|
|
-@@ -0,0 +1,3 @@
|
|
|
-+#if !__SH_FPU_ANY__ && !__SH4__
|
|
|
-+#include "../fenv.c"
|
|
|
-+#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/src/fenv/sh/fenv.S
|
|
|
-@@ -0,0 +1,78 @@
|
|
|
-+#if __SH_FPU_ANY__ || __SH4__
|
|
|
-+
|
|
|
-+.global fegetround
|
|
|
-+.type fegetround, @function
|
|
|
-+fegetround:
|
|
|
-+ sts fpscr, r0
|
|
|
-+ rts
|
|
|
-+ and #3, r0
|
|
|
-+
|
|
|
-+.global __fesetround
|
|
|
-+.type __fesetround, @function
|
|
|
-+__fesetround:
|
|
|
-+ sts fpscr, r0
|
|
|
-+ or r4, r0
|
|
|
-+ lds r0, fpscr
|
|
|
-+ rts
|
|
|
-+ mov #0, r0
|
|
|
-+
|
|
|
-+.global fetestexcept
|
|
|
-+.type fetestexcept, @function
|
|
|
-+fetestexcept:
|
|
|
-+ sts fpscr, r0
|
|
|
-+ and r4, r0
|
|
|
-+ rts
|
|
|
-+ and #0x7c, r0
|
|
|
-+
|
|
|
-+.global feclearexcept
|
|
|
-+.type feclearexcept, @function
|
|
|
-+feclearexcept:
|
|
|
-+ mov r4, r0
|
|
|
-+ and #0x7c, r0
|
|
|
-+ not r0, r4
|
|
|
-+ sts fpscr, r0
|
|
|
-+ and r4, r0
|
|
|
-+ lds r0, fpscr
|
|
|
-+ rts
|
|
|
-+ mov #0, r0
|
|
|
-+
|
|
|
-+.global feraiseexcept
|
|
|
-+.type feraiseexcept, @function
|
|
|
-+feraiseexcept:
|
|
|
-+ mov r4, r0
|
|
|
-+ and #0x7c, r0
|
|
|
-+ sts fpscr, r4
|
|
|
-+ or r4, r0
|
|
|
-+ lds r0, fpscr
|
|
|
-+ rts
|
|
|
-+ mov #0, r0
|
|
|
-+
|
|
|
-+.global fegetenv
|
|
|
-+.type fegetenv, @function
|
|
|
-+fegetenv:
|
|
|
-+ sts fpscr, r0
|
|
|
-+ mov.l r0, @r4
|
|
|
-+ rts
|
|
|
-+ mov #0, r0
|
|
|
-+
|
|
|
-+.global fesetenv
|
|
|
-+.type fesetenv, @function
|
|
|
-+fesetenv:
|
|
|
-+ mov r4, r0
|
|
|
-+ cmp/eq #-1, r0
|
|
|
-+ bf 1f
|
|
|
-+
|
|
|
-+ ! the default environment is complicated by the fact that we need to
|
|
|
-+ ! preserve the current precision bit, which we do not know a priori
|
|
|
-+ sts fpscr, r0
|
|
|
-+ mov #8, r1
|
|
|
-+ swap.w r1, r1
|
|
|
-+ bra 2f
|
|
|
-+ and r1, r0
|
|
|
-+
|
|
|
-+1: mov.l @r4, r0 ! non-default environment
|
|
|
-+2: lds r0, fpscr
|
|
|
-+ rts
|
|
|
-+ mov #0, r0
|
|
|
-+
|
|
|
-+#endif
|
|
|
---- a/src/fenv/sh/fenv.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,74 +0,0 @@
|
|
|
--.global fegetround
|
|
|
--.type fegetround, @function
|
|
|
--fegetround:
|
|
|
-- sts fpscr, r0
|
|
|
-- rts
|
|
|
-- and #3, r0
|
|
|
--
|
|
|
--.global __fesetround
|
|
|
--.type __fesetround, @function
|
|
|
--__fesetround:
|
|
|
-- sts fpscr, r0
|
|
|
-- or r4, r0
|
|
|
-- lds r0, fpscr
|
|
|
-- rts
|
|
|
-- mov #0, r0
|
|
|
--
|
|
|
--.global fetestexcept
|
|
|
--.type fetestexcept, @function
|
|
|
--fetestexcept:
|
|
|
-- sts fpscr, r0
|
|
|
-- and r4, r0
|
|
|
-- rts
|
|
|
-- and #0x7c, r0
|
|
|
--
|
|
|
--.global feclearexcept
|
|
|
--.type feclearexcept, @function
|
|
|
--feclearexcept:
|
|
|
-- mov r4, r0
|
|
|
-- and #0x7c, r0
|
|
|
-- not r0, r4
|
|
|
-- sts fpscr, r0
|
|
|
-- and r4, r0
|
|
|
-- lds r0, fpscr
|
|
|
-- rts
|
|
|
-- mov #0, r0
|
|
|
--
|
|
|
--.global feraiseexcept
|
|
|
--.type feraiseexcept, @function
|
|
|
--feraiseexcept:
|
|
|
-- mov r4, r0
|
|
|
-- and #0x7c, r0
|
|
|
-- sts fpscr, r4
|
|
|
-- or r4, r0
|
|
|
-- lds r0, fpscr
|
|
|
-- rts
|
|
|
-- mov #0, r0
|
|
|
--
|
|
|
--.global fegetenv
|
|
|
--.type fegetenv, @function
|
|
|
--fegetenv:
|
|
|
-- sts fpscr, r0
|
|
|
-- mov.l r0, @r4
|
|
|
-- rts
|
|
|
-- mov #0, r0
|
|
|
--
|
|
|
--.global fesetenv
|
|
|
--.type fesetenv, @function
|
|
|
--fesetenv:
|
|
|
-- mov r4, r0
|
|
|
-- cmp/eq #-1, r0
|
|
|
-- bf 1f
|
|
|
--
|
|
|
-- ! the default environment is complicated by the fact that we need to
|
|
|
-- ! preserve the current precision bit, which we do not know a priori
|
|
|
-- sts fpscr, r0
|
|
|
-- mov #8, r1
|
|
|
-- swap.w r1, r1
|
|
|
-- bra 2f
|
|
|
-- and r1, r0
|
|
|
--
|
|
|
--1: mov.l @r4, r0 ! non-default environment
|
|
|
--2: lds r0, fpscr
|
|
|
-- rts
|
|
|
-- mov #0, r0
|
|
|
---- a/src/fenv/sheb-nofpu/fenv.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../fenv.c
|
|
|
---- a/src/internal/arm/syscall.s
|
|
|
-+++ b/src/internal/arm/syscall.s
|
|
|
-@@ -1,3 +1,4 @@
|
|
|
-+.syntax unified
|
|
|
- .global __syscall
|
|
|
- .hidden __syscall
|
|
|
- .type __syscall,%function
|
|
|
-@@ -11,6 +12,4 @@ __syscall:
|
|
|
- ldmfd ip,{r3,r4,r5,r6}
|
|
|
- svc 0
|
|
|
- ldmfd sp!,{r4,r5,r6,r7}
|
|
|
-- tst lr,#1
|
|
|
-- moveq pc,lr
|
|
|
- bx lr
|
|
|
---- /dev/null
|
|
|
-+++ b/src/internal/atomic.h
|
|
|
-@@ -0,0 +1,275 @@
|
|
|
-+#ifndef _ATOMIC_H
|
|
|
-+#define _ATOMIC_H
|
|
|
-+
|
|
|
-+#include <stdint.h>
|
|
|
-+
|
|
|
-+#include "atomic_arch.h"
|
|
|
-+
|
|
|
-+#ifdef a_ll
|
|
|
-+
|
|
|
-+#ifndef a_pre_llsc
|
|
|
-+#define a_pre_llsc()
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_post_llsc
|
|
|
-+#define a_post_llsc()
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_cas
|
|
|
-+#define a_cas a_cas
|
|
|
-+static inline int a_cas(volatile int *p, int t, int s)
|
|
|
-+{
|
|
|
-+ int old;
|
|
|
-+ a_pre_llsc();
|
|
|
-+ do old = a_ll(p);
|
|
|
-+ while (old==t && !a_sc(p, s));
|
|
|
-+ a_post_llsc();
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_swap
|
|
|
-+#define a_swap a_swap
|
|
|
-+static inline int a_swap(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int old;
|
|
|
-+ a_pre_llsc();
|
|
|
-+ do old = a_ll(p);
|
|
|
-+ while (!a_sc(p, v));
|
|
|
-+ a_post_llsc();
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_fetch_add
|
|
|
-+#define a_fetch_add a_fetch_add
|
|
|
-+static inline int a_fetch_add(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int old;
|
|
|
-+ a_pre_llsc();
|
|
|
-+ do old = a_ll(p);
|
|
|
-+ while (!a_sc(p, (unsigned)old + v));
|
|
|
-+ a_post_llsc();
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_fetch_and
|
|
|
-+#define a_fetch_and a_fetch_and
|
|
|
-+static inline int a_fetch_and(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int old;
|
|
|
-+ a_pre_llsc();
|
|
|
-+ do old = a_ll(p);
|
|
|
-+ while (!a_sc(p, old & v));
|
|
|
-+ a_post_llsc();
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_fetch_or
|
|
|
-+#define a_fetch_or a_fetch_or
|
|
|
-+static inline int a_fetch_or(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int old;
|
|
|
-+ a_pre_llsc();
|
|
|
-+ do old = a_ll(p);
|
|
|
-+ while (!a_sc(p, old | v));
|
|
|
-+ a_post_llsc();
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_cas
|
|
|
-+#error missing definition of a_cas
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_swap
|
|
|
-+#define a_swap a_swap
|
|
|
-+static inline int a_swap(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int old;
|
|
|
-+ do old = *p;
|
|
|
-+ while (a_cas(p, old, v) != old);
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_fetch_add
|
|
|
-+#define a_fetch_add a_fetch_add
|
|
|
-+static inline int a_fetch_add(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int old;
|
|
|
-+ do old = *p;
|
|
|
-+ while (a_cas(p, old, (unsigned)old+v) != old);
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_fetch_and
|
|
|
-+#define a_fetch_and a_fetch_and
|
|
|
-+static inline int a_fetch_and(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int old;
|
|
|
-+ do old = *p;
|
|
|
-+ while (a_cas(p, old, old&v) != old);
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+#ifndef a_fetch_or
|
|
|
-+#define a_fetch_or a_fetch_or
|
|
|
-+static inline int a_fetch_or(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ int old;
|
|
|
-+ do old = *p;
|
|
|
-+ while (a_cas(p, old, old|v) != old);
|
|
|
-+ return old;
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_and
|
|
|
-+#define a_and a_and
|
|
|
-+static inline void a_and(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ a_fetch_and(p, v);
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_or
|
|
|
-+#define a_or a_or
|
|
|
-+static inline void a_or(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+ a_fetch_or(p, v);
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_inc
|
|
|
-+#define a_inc a_inc
|
|
|
-+static inline void a_inc(volatile int *p)
|
|
|
-+{
|
|
|
-+ a_fetch_add(p, 1);
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_dec
|
|
|
-+#define a_dec a_dec
|
|
|
-+static inline void a_dec(volatile int *p)
|
|
|
-+{
|
|
|
-+ a_fetch_add(p, -1);
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_store
|
|
|
-+#define a_store a_store
|
|
|
-+static inline void a_store(volatile int *p, int v)
|
|
|
-+{
|
|
|
-+#ifdef a_barrier
|
|
|
-+ a_barrier();
|
|
|
-+ *p = v;
|
|
|
-+ a_barrier();
|
|
|
-+#else
|
|
|
-+ a_swap(p, v);
|
|
|
-+#endif
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_barrier
|
|
|
-+#define a_barrier a_barrier
|
|
|
-+static void a_barrier()
|
|
|
-+{
|
|
|
-+ volatile int tmp = 0;
|
|
|
-+ a_cas(&tmp, 0, 0);
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_spin
|
|
|
-+#define a_spin a_barrier
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_and_64
|
|
|
-+#define a_and_64 a_and_64
|
|
|
-+static inline void a_and_64(volatile uint64_t *p, uint64_t v)
|
|
|
-+{
|
|
|
-+ union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-+ if (u.r[0]+1) a_and((int *)p, u.r[0]);
|
|
|
-+ if (u.r[1]+1) a_and((int *)p+1, u.r[1]);
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_or_64
|
|
|
-+#define a_or_64 a_or_64
|
|
|
-+static inline void a_or_64(volatile uint64_t *p, uint64_t v)
|
|
|
-+{
|
|
|
-+ union { uint64_t v; uint32_t r[2]; } u = { v };
|
|
|
-+ if (u.r[0]) a_or((int *)p, u.r[0]);
|
|
|
-+ if (u.r[1]) a_or((int *)p+1, u.r[1]);
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_cas_p
|
|
|
-+#define a_cas_p a_cas_p
|
|
|
-+static inline void *a_cas_p(volatile void *p, void *t, void *s)
|
|
|
-+{
|
|
|
-+ return (void *)a_cas((volatile int *)p, (int)t, (int)s);
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_or_l
|
|
|
-+#define a_or_l a_or_l
|
|
|
-+static inline void a_or_l(volatile void *p, long v)
|
|
|
-+{
|
|
|
-+ if (sizeof(long) == sizeof(int)) a_or(p, v);
|
|
|
-+ else a_or_64(p, v);
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_crash
|
|
|
-+#define a_crash a_crash
|
|
|
-+static inline void a_crash()
|
|
|
-+{
|
|
|
-+ *(volatile char *)0=0;
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_ctz_64
|
|
|
-+#define a_ctz_64 a_ctz_64
|
|
|
-+static inline int a_ctz_64(uint64_t x)
|
|
|
-+{
|
|
|
-+ static const char debruijn64[64] = {
|
|
|
-+ 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
|
|
|
-+ 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
|
|
|
-+ 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
|
|
|
-+ 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
|
|
|
-+ };
|
|
|
-+ static const char debruijn32[32] = {
|
|
|
-+ 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
|
|
|
-+ 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
|
|
|
-+ };
|
|
|
-+ if (sizeof(long) < 8) {
|
|
|
-+ uint32_t y = x;
|
|
|
-+ if (!y) {
|
|
|
-+ y = x>>32;
|
|
|
-+ return 32 + debruijn32[(y&-y)*0x076be629 >> 27];
|
|
|
-+ }
|
|
|
-+ return debruijn32[(y&-y)*0x076be629 >> 27];
|
|
|
-+ }
|
|
|
-+ return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#ifndef a_ctz_l
|
|
|
-+#define a_ctz_l a_ctz_l
|
|
|
-+static inline int a_ctz_l(unsigned long x)
|
|
|
-+{
|
|
|
-+ static const char debruijn32[32] = {
|
|
|
-+ 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
|
|
|
-+ 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
|
|
|
-+ };
|
|
|
-+ if (sizeof(long) == 8) return a_ctz_64(x);
|
|
|
-+ return debruijn32[(x&-x)*0x076be629 >> 27];
|
|
|
-+}
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+#endif
|
|
|
---- a/src/internal/dynlink.h
|
|
|
-+++ b/src/internal/dynlink.h
|
|
|
-@@ -64,6 +64,10 @@ struct fdpic_dummy_loadmap {
|
|
|
- #define DL_FDPIC 0
|
|
|
- #endif
|
|
|
-
|
|
|
-+#ifndef DL_NOMMU_SUPPORT
|
|
|
-+#define DL_NOMMU_SUPPORT 0
|
|
|
-+#endif
|
|
|
-+
|
|
|
- #if !DL_FDPIC
|
|
|
- #define IS_RELATIVE(x,s) ( \
|
|
|
- (R_TYPE(x) == REL_RELATIVE) || \
|
|
|
---- a/src/internal/libc.h
|
|
|
-+++ b/src/internal/libc.h
|
|
|
-@@ -11,13 +11,20 @@ struct __locale_struct {
|
|
|
- const struct __locale_map *volatile cat[6];
|
|
|
- };
|
|
|
-
|
|
|
-+struct tls_module {
|
|
|
-+ struct tls_module *next;
|
|
|
-+ void *image;
|
|
|
-+ size_t len, size, align, offset;
|
|
|
-+};
|
|
|
-+
|
|
|
- struct __libc {
|
|
|
- int can_do_threads;
|
|
|
- int threaded;
|
|
|
- int secure;
|
|
|
- volatile int threads_minus_1;
|
|
|
- size_t *auxv;
|
|
|
-- size_t tls_size;
|
|
|
-+ struct tls_module *tls_head;
|
|
|
-+ size_t tls_size, tls_align, tls_cnt;
|
|
|
- size_t page_size;
|
|
|
- struct __locale_struct global_locale;
|
|
|
- };
|
|
|
---- /dev/null
|
|
|
-+++ b/src/internal/sh/__shcall.c
|
|
|
-@@ -0,0 +1,5 @@
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+int __shcall(void *arg, int (*func)(void *))
|
|
|
-+{
|
|
|
-+ return func(arg);
|
|
|
-+}
|
|
|
---- a/src/internal/syscall.h
|
|
|
-+++ b/src/internal/syscall.h
|
|
|
-@@ -17,9 +17,7 @@
|
|
|
- typedef long syscall_arg_t;
|
|
|
- #endif
|
|
|
-
|
|
|
--#ifdef SHARED
|
|
|
- __attribute__((visibility("hidden")))
|
|
|
--#endif
|
|
|
- long __syscall_ret(unsigned long), __syscall(syscall_arg_t, ...),
|
|
|
- __syscall_cp(syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t,
|
|
|
- syscall_arg_t, syscall_arg_t, syscall_arg_t);
|
|
|
-@@ -65,7 +63,7 @@ long __syscall_ret(unsigned long), __sys
|
|
|
- #define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)
|
|
|
- #define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))
|
|
|
-
|
|
|
--#ifdef SYS_socket
|
|
|
-+#ifndef SYSCALL_USE_SOCKETCALL
|
|
|
- #define __socketcall(nm,a,b,c,d,e,f) syscall(SYS_##nm, a, b, c, d, e, f)
|
|
|
- #define __socketcall_cp(nm,a,b,c,d,e,f) syscall_cp(SYS_##nm, a, b, c, d, e, f)
|
|
|
- #else
|
|
|
---- a/src/internal/version.c
|
|
|
-+++ b/src/internal/version.c
|
|
|
-@@ -1,12 +1,9 @@
|
|
|
--#ifdef SHARED
|
|
|
--
|
|
|
- #include "version.h"
|
|
|
-
|
|
|
- static const char version[] = VERSION;
|
|
|
-
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
- const char *__libc_get_version()
|
|
|
- {
|
|
|
- return version;
|
|
|
- }
|
|
|
--
|
|
|
--#endif
|
|
|
---- a/src/internal/vis.h
|
|
|
-+++ b/src/internal/vis.h
|
|
|
-@@ -4,10 +4,9 @@
|
|
|
- * override default visibilities to reduce the size and performance costs
|
|
|
- * of position-independent code. */
|
|
|
-
|
|
|
--#ifndef CRT
|
|
|
--#ifdef SHARED
|
|
|
-+#if !defined(CRT) && !defined(__ASSEMBLER__)
|
|
|
-
|
|
|
--/* For shared libc.so, all symbols should be protected, but some toolchains
|
|
|
-+/* Conceptually, all symbols should be protected, but some toolchains
|
|
|
- * fail to support copy relocations for protected data, so exclude all
|
|
|
- * exported data symbols. */
|
|
|
-
|
|
|
-@@ -25,16 +24,4 @@ extern char *optarg, **environ, **__envi
|
|
|
-
|
|
|
- #pragma GCC visibility push(protected)
|
|
|
-
|
|
|
--#elif defined(__PIC__)
|
|
|
--
|
|
|
--/* If building static libc.a as position-independent code, try to make
|
|
|
-- * everything hidden except possibly-undefined weak references. */
|
|
|
--
|
|
|
--__attribute__((__visibility__("default")))
|
|
|
--extern void (*const __init_array_start)(), (*const __init_array_end)(),
|
|
|
-- (*const __fini_array_start)(), (*const __fini_array_end)();
|
|
|
--
|
|
|
--#pragma GCC visibility push(hidden)
|
|
|
--
|
|
|
--#endif
|
|
|
- #endif
|
|
|
---- /dev/null
|
|
|
-+++ b/src/ldso/__dlsym.c
|
|
|
-@@ -0,0 +1,13 @@
|
|
|
-+#include <dlfcn.h>
|
|
|
-+#include "libc.h"
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+void __dl_seterr(const char *, ...);
|
|
|
-+
|
|
|
-+static void *stub_dlsym(void *restrict p, const char *restrict s, void *restrict ra)
|
|
|
-+{
|
|
|
-+ __dl_seterr("Symbol not found: %s", s);
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+weak_alias(stub_dlsym, __dlsym);
|
|
|
---- a/src/ldso/arm/dlsym.s
|
|
|
-+++ b/src/ldso/arm/dlsym.s
|
|
|
-@@ -1,3 +1,4 @@
|
|
|
-+.syntax unified
|
|
|
- .text
|
|
|
- .global dlsym
|
|
|
- .hidden __dlsym
|
|
|
---- /dev/null
|
|
|
-+++ b/src/ldso/arm/find_exidx.c
|
|
|
-@@ -0,0 +1,42 @@
|
|
|
-+#define _GNU_SOURCE
|
|
|
-+#include <link.h>
|
|
|
-+#include <stdint.h>
|
|
|
-+
|
|
|
-+struct find_exidx_data {
|
|
|
-+ uintptr_t pc, exidx_start;
|
|
|
-+ int exidx_len;
|
|
|
-+};
|
|
|
-+
|
|
|
-+static int find_exidx(struct dl_phdr_info *info, size_t size, void *ptr)
|
|
|
-+{
|
|
|
-+ struct find_exidx_data *data = ptr;
|
|
|
-+ const ElfW(Phdr) *phdr = info->dlpi_phdr;
|
|
|
-+ uintptr_t addr, exidx_start = 0;
|
|
|
-+ int i, match = 0, exidx_len = 0;
|
|
|
-+
|
|
|
-+ for (i = info->dlpi_phnum; i > 0; i--, phdr++) {
|
|
|
-+ addr = info->dlpi_addr + phdr->p_vaddr;
|
|
|
-+ switch (phdr->p_type) {
|
|
|
-+ case PT_LOAD:
|
|
|
-+ match |= data->pc >= addr && data->pc < addr + phdr->p_memsz;
|
|
|
-+ break;
|
|
|
-+ case PT_ARM_EXIDX:
|
|
|
-+ exidx_start = addr;
|
|
|
-+ exidx_len = phdr->p_memsz;
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ data->exidx_start = exidx_start;
|
|
|
-+ data->exidx_len = exidx_len;
|
|
|
-+ return match;
|
|
|
-+}
|
|
|
-+
|
|
|
-+uintptr_t __gnu_Unwind_Find_exidx(uintptr_t pc, int *pcount)
|
|
|
-+{
|
|
|
-+ struct find_exidx_data data;
|
|
|
-+ data.pc = pc;
|
|
|
-+ if (dl_iterate_phdr(find_exidx, &data) <= 0)
|
|
|
-+ return 0;
|
|
|
-+ *pcount = data.exidx_len / 8;
|
|
|
-+ return data.exidx_start;
|
|
|
-+}
|
|
|
---- a/src/ldso/dl_iterate_phdr.c
|
|
|
-+++ b/src/ldso/dl_iterate_phdr.c
|
|
|
-@@ -1,12 +1,10 @@
|
|
|
--#ifndef SHARED
|
|
|
--
|
|
|
- #include <elf.h>
|
|
|
- #include <link.h>
|
|
|
- #include "libc.h"
|
|
|
-
|
|
|
- #define AUX_CNT 38
|
|
|
-
|
|
|
--int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
|
|
|
-+static int static_dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
|
|
|
- {
|
|
|
- unsigned char *p;
|
|
|
- ElfW(Phdr) *phdr, *tls_phdr=0;
|
|
|
-@@ -40,4 +38,5 @@ int dl_iterate_phdr(int(*callback)(struc
|
|
|
- }
|
|
|
- return (callback)(&info, sizeof (info), data);
|
|
|
- }
|
|
|
--#endif
|
|
|
-+
|
|
|
-+weak_alias(static_dl_iterate_phdr, dl_iterate_phdr);
|
|
|
---- a/src/ldso/dladdr.c
|
|
|
-+++ b/src/ldso/dladdr.c
|
|
|
-@@ -1,9 +1,10 @@
|
|
|
- #define _GNU_SOURCE
|
|
|
- #include <dlfcn.h>
|
|
|
-+#include "libc.h"
|
|
|
-
|
|
|
--int __dladdr(const void *, Dl_info *);
|
|
|
--
|
|
|
--int dladdr(const void *addr, Dl_info *info)
|
|
|
-+static int stub_dladdr(const void *addr, Dl_info *info)
|
|
|
- {
|
|
|
-- return __dladdr(addr, info);
|
|
|
-+ return 0;
|
|
|
- }
|
|
|
-+
|
|
|
-+weak_alias(stub_dladdr, dladdr);
|
|
|
---- /dev/null
|
|
|
-+++ b/src/ldso/dlclose.c
|
|
|
-@@ -0,0 +1,9 @@
|
|
|
-+#include <dlfcn.h>
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+int __dl_invalid_handle(void *);
|
|
|
-+
|
|
|
-+int dlclose(void *p)
|
|
|
-+{
|
|
|
-+ return __dl_invalid_handle(p);
|
|
|
-+}
|
|
|
---- /dev/null
|
|
|
-+++ b/src/ldso/dlerror.c
|
|
|
-@@ -0,0 +1,64 @@
|
|
|
-+#include <dlfcn.h>
|
|
|
-+#include <stdlib.h>
|
|
|
-+#include <stdarg.h>
|
|
|
-+#include "pthread_impl.h"
|
|
|
-+#include "libc.h"
|
|
|
-+
|
|
|
-+char *dlerror()
|
|
|
-+{
|
|
|
-+ pthread_t self = __pthread_self();
|
|
|
-+ if (!self->dlerror_flag) return 0;
|
|
|
-+ self->dlerror_flag = 0;
|
|
|
-+ char *s = self->dlerror_buf;
|
|
|
-+ if (s == (void *)-1)
|
|
|
-+ return "Dynamic linker failed to allocate memory for error message";
|
|
|
-+ else
|
|
|
-+ return s;
|
|
|
-+}
|
|
|
-+
|
|
|
-+void __dl_thread_cleanup(void)
|
|
|
-+{
|
|
|
-+ pthread_t self = __pthread_self();
|
|
|
-+ if (self->dlerror_buf != (void *)-1)
|
|
|
-+ free(self->dlerror_buf);
|
|
|
-+}
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+void __dl_vseterr(const char *fmt, va_list ap)
|
|
|
-+{
|
|
|
-+ va_list ap2;
|
|
|
-+ va_copy(ap2, ap);
|
|
|
-+ pthread_t self = __pthread_self();
|
|
|
-+ if (self->dlerror_buf != (void *)-1)
|
|
|
-+ free(self->dlerror_buf);
|
|
|
-+ size_t len = vsnprintf(0, 0, fmt, ap2);
|
|
|
-+ va_end(ap2);
|
|
|
-+ char *buf = malloc(len+1);
|
|
|
-+ if (buf) {
|
|
|
-+ vsnprintf(buf, len+1, fmt, ap);
|
|
|
-+ } else {
|
|
|
-+ buf = (void *)-1;
|
|
|
-+ }
|
|
|
-+ self->dlerror_buf = buf;
|
|
|
-+ self->dlerror_flag = 1;
|
|
|
-+}
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+void __dl_seterr(const char *fmt, ...)
|
|
|
-+{
|
|
|
-+ va_list ap;
|
|
|
-+ va_start(ap, fmt);
|
|
|
-+ __dl_vseterr(fmt, ap);
|
|
|
-+ va_end(ap);
|
|
|
-+}
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+int __dl_invalid_handle(void *);
|
|
|
-+
|
|
|
-+static int stub_invalid_handle(void *h)
|
|
|
-+{
|
|
|
-+ __dl_seterr("Invalid library handle %p", (void *)h);
|
|
|
-+ return 1;
|
|
|
-+}
|
|
|
-+
|
|
|
-+weak_alias(stub_invalid_handle, __dl_invalid_handle);
|
|
|
---- a/src/ldso/dlinfo.c
|
|
|
-+++ b/src/ldso/dlinfo.c
|
|
|
-@@ -1,9 +1,19 @@
|
|
|
- #define _GNU_SOURCE
|
|
|
- #include <dlfcn.h>
|
|
|
-
|
|
|
--int __dlinfo(void *, int, void *);
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+int __dl_invalid_handle(void *);
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+void __dl_seterr(const char *, ...);
|
|
|
-
|
|
|
- int dlinfo(void *dso, int req, void *res)
|
|
|
- {
|
|
|
-- return __dlinfo(dso, req, res);
|
|
|
-+ if (__dl_invalid_handle(dso)) return -1;
|
|
|
-+ if (req != RTLD_DI_LINKMAP) {
|
|
|
-+ __dl_seterr("Unsupported request %d", req);
|
|
|
-+ return -1;
|
|
|
-+ }
|
|
|
-+ *(struct link_map **)res = dso;
|
|
|
-+ return 0;
|
|
|
- }
|
|
|
---- /dev/null
|
|
|
-+++ b/src/ldso/dlopen.c
|
|
|
-@@ -0,0 +1,13 @@
|
|
|
-+#include <dlfcn.h>
|
|
|
-+#include "libc.h"
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+void __dl_seterr(const char *, ...);
|
|
|
-+
|
|
|
-+static void *stub_dlopen(const char *file, int mode)
|
|
|
-+{
|
|
|
-+ __dl_seterr("Dynamic loading not supported");
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
-+
|
|
|
-+weak_alias(stub_dlopen, dlopen);
|
|
|
---- a/src/ldso/dlstart.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,150 +0,0 @@
|
|
|
--#include <stddef.h>
|
|
|
--#include "dynlink.h"
|
|
|
--
|
|
|
--#ifdef SHARED
|
|
|
--
|
|
|
--#ifndef START
|
|
|
--#define START "_dlstart"
|
|
|
--#endif
|
|
|
--
|
|
|
--#include "crt_arch.h"
|
|
|
--
|
|
|
--#ifndef GETFUNCSYM
|
|
|
--#define GETFUNCSYM(fp, sym, got) do { \
|
|
|
-- __attribute__((__visibility__("hidden"))) void sym(); \
|
|
|
-- static void (*static_func_ptr)() = sym; \
|
|
|
-- __asm__ __volatile__ ( "" : "+m"(static_func_ptr) : : "memory"); \
|
|
|
-- *(fp) = static_func_ptr; } while(0)
|
|
|
--#endif
|
|
|
--
|
|
|
--__attribute__((__visibility__("hidden")))
|
|
|
--void _dlstart_c(size_t *sp, size_t *dynv)
|
|
|
--{
|
|
|
-- size_t i, aux[AUX_CNT], dyn[DYN_CNT];
|
|
|
-- size_t *rel, rel_size, base;
|
|
|
--
|
|
|
-- int argc = *sp;
|
|
|
-- char **argv = (void *)(sp+1);
|
|
|
--
|
|
|
-- for (i=argc+1; argv[i]; i++);
|
|
|
-- size_t *auxv = (void *)(argv+i+1);
|
|
|
--
|
|
|
-- for (i=0; i<AUX_CNT; i++) aux[i] = 0;
|
|
|
-- for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT)
|
|
|
-- aux[auxv[i]] = auxv[i+1];
|
|
|
--
|
|
|
--#if DL_FDPIC
|
|
|
-- struct fdpic_loadseg *segs, fakeseg;
|
|
|
-- size_t j;
|
|
|
-- if (dynv) {
|
|
|
-- /* crt_arch.h entry point asm is responsible for reserving
|
|
|
-- * space and moving the extra fdpic arguments to the stack
|
|
|
-- * vector where they are easily accessible from C. */
|
|
|
-- segs = ((struct fdpic_loadmap *)(sp[-1] ? sp[-1] : sp[-2]))->segs;
|
|
|
-- } else {
|
|
|
-- /* If dynv is null, the entry point was started from loader
|
|
|
-- * that is not fdpic-aware. We can assume normal fixed-
|
|
|
-- * displacement ELF loading was performed, but when ldso was
|
|
|
-- * run as a command, finding the Ehdr is a heursitic: we
|
|
|
-- * have to assume Phdrs start in the first 4k of the file. */
|
|
|
-- base = aux[AT_BASE];
|
|
|
-- if (!base) base = aux[AT_PHDR] & -4096;
|
|
|
-- segs = &fakeseg;
|
|
|
-- segs[0].addr = base;
|
|
|
-- segs[0].p_vaddr = 0;
|
|
|
-- segs[0].p_memsz = -1;
|
|
|
-- Ehdr *eh = (void *)base;
|
|
|
-- Phdr *ph = (void *)(base + eh->e_phoff);
|
|
|
-- size_t phnum = eh->e_phnum;
|
|
|
-- size_t phent = eh->e_phentsize;
|
|
|
-- while (phnum-- && ph->p_type != PT_DYNAMIC)
|
|
|
-- ph = (void *)((size_t)ph + phent);
|
|
|
-- dynv = (void *)(base + ph->p_vaddr);
|
|
|
-- }
|
|
|
--#endif
|
|
|
--
|
|
|
-- for (i=0; i<DYN_CNT; i++) dyn[i] = 0;
|
|
|
-- for (i=0; dynv[i]; i+=2) if (dynv[i]<DYN_CNT)
|
|
|
-- dyn[dynv[i]] = dynv[i+1];
|
|
|
--
|
|
|
--#if DL_FDPIC
|
|
|
-- for (i=0; i<DYN_CNT; i++) {
|
|
|
-- if (i==DT_RELASZ || i==DT_RELSZ) continue;
|
|
|
-- if (!dyn[i]) continue;
|
|
|
-- for (j=0; dyn[i]-segs[j].p_vaddr >= segs[j].p_memsz; j++);
|
|
|
-- dyn[i] += segs[j].addr - segs[j].p_vaddr;
|
|
|
-- }
|
|
|
-- base = 0;
|
|
|
--
|
|
|
-- const Sym *syms = (void *)dyn[DT_SYMTAB];
|
|
|
--
|
|
|
-- rel = (void *)dyn[DT_RELA];
|
|
|
-- rel_size = dyn[DT_RELASZ];
|
|
|
-- for (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) {
|
|
|
-- if (!IS_RELATIVE(rel[1], syms)) continue;
|
|
|
-- for (j=0; rel[0]-segs[j].p_vaddr >= segs[j].p_memsz; j++);
|
|
|
-- size_t *rel_addr = (void *)
|
|
|
-- (rel[0] + segs[j].addr - segs[j].p_vaddr);
|
|
|
-- if (R_TYPE(rel[1]) == REL_FUNCDESC_VAL) {
|
|
|
-- *rel_addr += segs[rel_addr[1]].addr
|
|
|
-- - segs[rel_addr[1]].p_vaddr
|
|
|
-- + syms[R_SYM(rel[1])].st_value;
|
|
|
-- rel_addr[1] = dyn[DT_PLTGOT];
|
|
|
-- } else {
|
|
|
-- size_t val = syms[R_SYM(rel[1])].st_value;
|
|
|
-- for (j=0; val-segs[j].p_vaddr >= segs[j].p_memsz; j++);
|
|
|
-- *rel_addr = rel[2] + segs[j].addr - segs[j].p_vaddr + val;
|
|
|
-- }
|
|
|
-- }
|
|
|
--#else
|
|
|
-- /* If the dynamic linker is invoked as a command, its load
|
|
|
-- * address is not available in the aux vector. Instead, compute
|
|
|
-- * the load address as the difference between &_DYNAMIC and the
|
|
|
-- * virtual address in the PT_DYNAMIC program header. */
|
|
|
-- base = aux[AT_BASE];
|
|
|
-- if (!base) {
|
|
|
-- size_t phnum = aux[AT_PHNUM];
|
|
|
-- size_t phentsize = aux[AT_PHENT];
|
|
|
-- Phdr *ph = (void *)aux[AT_PHDR];
|
|
|
-- for (i=phnum; i--; ph = (void *)((char *)ph + phentsize)) {
|
|
|
-- if (ph->p_type == PT_DYNAMIC) {
|
|
|
-- base = (size_t)dynv - ph->p_vaddr;
|
|
|
-- break;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- }
|
|
|
--
|
|
|
-- /* MIPS uses an ugly packed form for GOT relocations. Since we
|
|
|
-- * can't make function calls yet and the code is tiny anyway,
|
|
|
-- * it's simply inlined here. */
|
|
|
-- if (NEED_MIPS_GOT_RELOCS) {
|
|
|
-- size_t local_cnt = 0;
|
|
|
-- size_t *got = (void *)(base + dyn[DT_PLTGOT]);
|
|
|
-- for (i=0; dynv[i]; i+=2) if (dynv[i]==DT_MIPS_LOCAL_GOTNO)
|
|
|
-- local_cnt = dynv[i+1];
|
|
|
-- for (i=0; i<local_cnt; i++) got[i] += base;
|
|
|
-- }
|
|
|
--
|
|
|
-- rel = (void *)(base+dyn[DT_REL]);
|
|
|
-- rel_size = dyn[DT_RELSZ];
|
|
|
-- for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t)) {
|
|
|
-- if (!IS_RELATIVE(rel[1], 0)) continue;
|
|
|
-- size_t *rel_addr = (void *)(base + rel[0]);
|
|
|
-- *rel_addr += base;
|
|
|
-- }
|
|
|
--
|
|
|
-- rel = (void *)(base+dyn[DT_RELA]);
|
|
|
-- rel_size = dyn[DT_RELASZ];
|
|
|
-- for (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) {
|
|
|
-- if (!IS_RELATIVE(rel[1], 0)) continue;
|
|
|
-- size_t *rel_addr = (void *)(base + rel[0]);
|
|
|
-- *rel_addr = base + rel[2];
|
|
|
-- }
|
|
|
--#endif
|
|
|
--
|
|
|
-- stage2_func dls2;
|
|
|
-- GETFUNCSYM(&dls2, __dls2, base+dyn[DT_PLTGOT]);
|
|
|
-- dls2((void *)base, sp);
|
|
|
--}
|
|
|
--
|
|
|
--#endif
|
|
|
---- a/src/ldso/dynlink.c
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,2000 +0,0 @@
|
|
|
--#define _GNU_SOURCE
|
|
|
--#include <stdio.h>
|
|
|
--#include <stdlib.h>
|
|
|
--#include <stdarg.h>
|
|
|
--#include <stddef.h>
|
|
|
--#include <string.h>
|
|
|
--#include <unistd.h>
|
|
|
--#include <stdint.h>
|
|
|
--#include <elf.h>
|
|
|
--#include <sys/mman.h>
|
|
|
--#include <limits.h>
|
|
|
--#include <fcntl.h>
|
|
|
--#include <sys/stat.h>
|
|
|
--#include <errno.h>
|
|
|
--#include <link.h>
|
|
|
--#include <setjmp.h>
|
|
|
--#include <pthread.h>
|
|
|
--#include <ctype.h>
|
|
|
--#include <dlfcn.h>
|
|
|
--#include "pthread_impl.h"
|
|
|
--#include "libc.h"
|
|
|
--#include "dynlink.h"
|
|
|
--
|
|
|
--static void error(const char *, ...);
|
|
|
--
|
|
|
--#ifdef SHARED
|
|
|
--
|
|
|
--#define MAXP2(a,b) (-(-(a)&-(b)))
|
|
|
--#define ALIGN(x,y) ((x)+(y)-1 & -(y))
|
|
|
--
|
|
|
--struct debug {
|
|
|
-- int ver;
|
|
|
-- void *head;
|
|
|
-- void (*bp)(void);
|
|
|
-- int state;
|
|
|
-- void *base;
|
|
|
--};
|
|
|
--
|
|
|
--struct td_index {
|
|
|
-- size_t args[2];
|
|
|
-- struct td_index *next;
|
|
|
--};
|
|
|
--
|
|
|
--struct dso {
|
|
|
--#if DL_FDPIC
|
|
|
-- struct fdpic_loadmap *loadmap;
|
|
|
--#else
|
|
|
-- unsigned char *base;
|
|
|
--#endif
|
|
|
-- char *name;
|
|
|
-- size_t *dynv;
|
|
|
-- struct dso *next, *prev;
|
|
|
--
|
|
|
-- Phdr *phdr;
|
|
|
-- int phnum;
|
|
|
-- size_t phentsize;
|
|
|
-- int refcnt;
|
|
|
-- Sym *syms;
|
|
|
-- uint32_t *hashtab;
|
|
|
-- uint32_t *ghashtab;
|
|
|
-- int16_t *versym;
|
|
|
-- char *strings;
|
|
|
-- unsigned char *map;
|
|
|
-- size_t map_len;
|
|
|
-- dev_t dev;
|
|
|
-- ino_t ino;
|
|
|
-- signed char global;
|
|
|
-- char relocated;
|
|
|
-- char constructed;
|
|
|
-- char kernel_mapped;
|
|
|
-- struct dso **deps, *needed_by;
|
|
|
-- char *rpath_orig, *rpath;
|
|
|
-- void *tls_image;
|
|
|
-- size_t tls_len, tls_size, tls_align, tls_id, tls_offset;
|
|
|
-- size_t relro_start, relro_end;
|
|
|
-- void **new_dtv;
|
|
|
-- unsigned char *new_tls;
|
|
|
-- volatile int new_dtv_idx, new_tls_idx;
|
|
|
-- struct td_index *td_index;
|
|
|
-- struct dso *fini_next;
|
|
|
-- char *shortname;
|
|
|
--#if DL_FDPIC
|
|
|
-- unsigned char *base;
|
|
|
--#else
|
|
|
-- struct fdpic_loadmap *loadmap;
|
|
|
--#endif
|
|
|
-- struct funcdesc {
|
|
|
-- void *addr;
|
|
|
-- size_t *got;
|
|
|
-- } *funcdescs;
|
|
|
-- size_t *got;
|
|
|
-- char buf[];
|
|
|
--};
|
|
|
--
|
|
|
--struct symdef {
|
|
|
-- Sym *sym;
|
|
|
-- struct dso *dso;
|
|
|
--};
|
|
|
--
|
|
|
--int __init_tp(void *);
|
|
|
--void __init_libc(char **, char *);
|
|
|
--
|
|
|
--const char *__libc_get_version(void);
|
|
|
--
|
|
|
--static struct builtin_tls {
|
|
|
-- char c;
|
|
|
-- struct pthread pt;
|
|
|
-- void *space[16];
|
|
|
--} builtin_tls[1];
|
|
|
--#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
|
|
|
--
|
|
|
--#define ADDEND_LIMIT 4096
|
|
|
--static size_t *saved_addends, *apply_addends_to;
|
|
|
--
|
|
|
--static struct dso ldso;
|
|
|
--static struct dso *head, *tail, *fini_head;
|
|
|
--static char *env_path, *sys_path;
|
|
|
--static unsigned long long gencnt;
|
|
|
--static int runtime;
|
|
|
--static int ldd_mode;
|
|
|
--static int ldso_fail;
|
|
|
--static int noload;
|
|
|
--static jmp_buf *rtld_fail;
|
|
|
--static pthread_rwlock_t lock;
|
|
|
--static struct debug debug;
|
|
|
--static size_t tls_cnt, tls_offset, tls_align = MIN_TLS_ALIGN;
|
|
|
--static size_t static_tls_cnt;
|
|
|
--static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE };
|
|
|
--static struct fdpic_loadmap *app_loadmap;
|
|
|
--static struct fdpic_dummy_loadmap app_dummy_loadmap;
|
|
|
--
|
|
|
--struct debug *_dl_debug_addr = &debug;
|
|
|
--
|
|
|
--static int dl_strcmp(const char *l, const char *r)
|
|
|
--{
|
|
|
-- for (; *l==*r && *l; l++, r++);
|
|
|
-- return *(unsigned char *)l - *(unsigned char *)r;
|
|
|
--}
|
|
|
--#define strcmp(l,r) dl_strcmp(l,r)
|
|
|
--
|
|
|
--/* Compute load address for a virtual address in a given dso. */
|
|
|
--#if DL_FDPIC
|
|
|
--static void *laddr(const struct dso *p, size_t v)
|
|
|
--{
|
|
|
-- size_t j=0;
|
|
|
-- if (!p->loadmap) return p->base + v;
|
|
|
-- for (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz; j++);
|
|
|
-- return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr);
|
|
|
--}
|
|
|
--#define fpaddr(p, v) ((void (*)())&(struct funcdesc){ \
|
|
|
-- laddr(p, v), (p)->got })
|
|
|
--#else
|
|
|
--#define laddr(p, v) (void *)((p)->base + (v))
|
|
|
--#define fpaddr(p, v) ((void (*)())laddr(p, v))
|
|
|
--#endif
|
|
|
--
|
|
|
--static void decode_vec(size_t *v, size_t *a, size_t cnt)
|
|
|
--{
|
|
|
-- size_t i;
|
|
|
-- for (i=0; i<cnt; i++) a[i] = 0;
|
|
|
-- for (; v[0]; v+=2) if (v[0]-1<cnt-1) {
|
|
|
-- a[0] |= 1UL<<v[0];
|
|
|
-- a[v[0]] = v[1];
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--static int search_vec(size_t *v, size_t *r, size_t key)
|
|
|
--{
|
|
|
-- for (; v[0]!=key; v+=2)
|
|
|
-- if (!v[0]) return 0;
|
|
|
-- *r = v[1];
|
|
|
-- return 1;
|
|
|
--}
|
|
|
--
|
|
|
--static uint32_t sysv_hash(const char *s0)
|
|
|
--{
|
|
|
-- const unsigned char *s = (void *)s0;
|
|
|
-- uint_fast32_t h = 0;
|
|
|
-- while (*s) {
|
|
|
-- h = 16*h + *s++;
|
|
|
-- h ^= h>>24 & 0xf0;
|
|
|
-- }
|
|
|
-- return h & 0xfffffff;
|
|
|
--}
|
|
|
--
|
|
|
--static uint32_t gnu_hash(const char *s0)
|
|
|
--{
|
|
|
-- const unsigned char *s = (void *)s0;
|
|
|
-- uint_fast32_t h = 5381;
|
|
|
-- for (; *s; s++)
|
|
|
-- h += h*32 + *s;
|
|
|
-- return h;
|
|
|
--}
|
|
|
--
|
|
|
--static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso)
|
|
|
--{
|
|
|
-- size_t i;
|
|
|
-- Sym *syms = dso->syms;
|
|
|
-- uint32_t *hashtab = dso->hashtab;
|
|
|
-- char *strings = dso->strings;
|
|
|
-- for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) {
|
|
|
-- if ((!dso->versym || dso->versym[i] >= 0)
|
|
|
-- && (!strcmp(s, strings+syms[i].st_name)))
|
|
|
-- return syms+i;
|
|
|
-- }
|
|
|
-- return 0;
|
|
|
--}
|
|
|
--
|
|
|
--static Sym *gnu_lookup(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s)
|
|
|
--{
|
|
|
-- uint32_t nbuckets = hashtab[0];
|
|
|
-- uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);
|
|
|
-- uint32_t i = buckets[h1 % nbuckets];
|
|
|
--
|
|
|
-- if (!i) return 0;
|
|
|
--
|
|
|
-- uint32_t *hashval = buckets + nbuckets + (i - hashtab[1]);
|
|
|
--
|
|
|
-- for (h1 |= 1; ; i++) {
|
|
|
-- uint32_t h2 = *hashval++;
|
|
|
-- if ((h1 == (h2|1)) && (!dso->versym || dso->versym[i] >= 0)
|
|
|
-- && !strcmp(s, dso->strings + dso->syms[i].st_name))
|
|
|
-- return dso->syms+i;
|
|
|
-- if (h2 & 1) break;
|
|
|
-- }
|
|
|
--
|
|
|
-- return 0;
|
|
|
--}
|
|
|
--
|
|
|
--static Sym *gnu_lookup_filtered(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s, uint32_t fofs, size_t fmask)
|
|
|
--{
|
|
|
-- const size_t *bloomwords = (const void *)(hashtab+4);
|
|
|
-- size_t f = bloomwords[fofs & (hashtab[2]-1)];
|
|
|
-- if (!(f & fmask)) return 0;
|
|
|
--
|
|
|
-- f >>= (h1 >> hashtab[3]) % (8 * sizeof f);
|
|
|
-- if (!(f & 1)) return 0;
|
|
|
--
|
|
|
-- return gnu_lookup(h1, hashtab, dso, s);
|
|
|
--}
|
|
|
--
|
|
|
--#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
|
|
|
--#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
|
|
|
--
|
|
|
--#ifndef ARCH_SYM_REJECT_UND
|
|
|
--#define ARCH_SYM_REJECT_UND(s) 0
|
|
|
--#endif
|
|
|
--
|
|
|
--static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
|
|
|
--{
|
|
|
-- uint32_t h = 0, gh, gho, *ght;
|
|
|
-- size_t ghm = 0;
|
|
|
-- struct symdef def = {0};
|
|
|
-- for (; dso; dso=dso->next) {
|
|
|
-- Sym *sym;
|
|
|
-- if (!dso->global) continue;
|
|
|
-- if ((ght = dso->ghashtab)) {
|
|
|
-- if (!ghm) {
|
|
|
-- gh = gnu_hash(s);
|
|
|
-- int maskbits = 8 * sizeof ghm;
|
|
|
-- gho = gh / maskbits;
|
|
|
-- ghm = 1ul << gh % maskbits;
|
|
|
-- }
|
|
|
-- sym = gnu_lookup_filtered(gh, ght, dso, s, gho, ghm);
|
|
|
-- } else {
|
|
|
-- if (!h) h = sysv_hash(s);
|
|
|
-- sym = sysv_lookup(s, h, dso);
|
|
|
-- }
|
|
|
-- if (!sym) continue;
|
|
|
-- if (!sym->st_shndx)
|
|
|
-- if (need_def || (sym->st_info&0xf) == STT_TLS
|
|
|
-- || ARCH_SYM_REJECT_UND(sym))
|
|
|
-- continue;
|
|
|
-- if (!sym->st_value)
|
|
|
-- if ((sym->st_info&0xf) != STT_TLS)
|
|
|
-- continue;
|
|
|
-- if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;
|
|
|
-- if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;
|
|
|
--
|
|
|
-- if (def.sym && sym->st_info>>4 == STB_WEAK) continue;
|
|
|
-- def.sym = sym;
|
|
|
-- def.dso = dso;
|
|
|
-- if (sym->st_info>>4 == STB_GLOBAL) break;
|
|
|
-- }
|
|
|
-- return def;
|
|
|
--}
|
|
|
--
|
|
|
--__attribute__((__visibility__("hidden")))
|
|
|
--ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic();
|
|
|
--
|
|
|
--static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)
|
|
|
--{
|
|
|
-- unsigned char *base = dso->base;
|
|
|
-- Sym *syms = dso->syms;
|
|
|
-- char *strings = dso->strings;
|
|
|
-- Sym *sym;
|
|
|
-- const char *name;
|
|
|
-- void *ctx;
|
|
|
-- int type;
|
|
|
-- int sym_index;
|
|
|
-- struct symdef def;
|
|
|
-- size_t *reloc_addr;
|
|
|
-- size_t sym_val;
|
|
|
-- size_t tls_val;
|
|
|
-- size_t addend;
|
|
|
-- int skip_relative = 0, reuse_addends = 0, save_slot = 0;
|
|
|
--
|
|
|
-- if (dso == &ldso) {
|
|
|
-- /* Only ldso's REL table needs addend saving/reuse. */
|
|
|
-- if (rel == apply_addends_to)
|
|
|
-- reuse_addends = 1;
|
|
|
-- skip_relative = 1;
|
|
|
-- }
|
|
|
--
|
|
|
-- for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
|
|
|
-- if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue;
|
|
|
-- type = R_TYPE(rel[1]);
|
|
|
-- if (type == REL_NONE) continue;
|
|
|
-- sym_index = R_SYM(rel[1]);
|
|
|
-- reloc_addr = laddr(dso, rel[0]);
|
|
|
-- if (sym_index) {
|
|
|
-- sym = syms + sym_index;
|
|
|
-- name = strings + sym->st_name;
|
|
|
-- ctx = type==REL_COPY ? head->next : head;
|
|
|
-- def = (sym->st_info&0xf) == STT_SECTION
|
|
|
-- ? (struct symdef){ .dso = dso, .sym = sym }
|
|
|
-- : find_sym(ctx, name, type==REL_PLT);
|
|
|
-- if (!def.sym && (sym->st_shndx != SHN_UNDEF
|
|
|
-- || sym->st_info>>4 != STB_WEAK)) {
|
|
|
-- error("Error relocating %s: %s: symbol not found",
|
|
|
-- dso->name, name);
|
|
|
-- if (runtime) longjmp(*rtld_fail, 1);
|
|
|
-- continue;
|
|
|
-- }
|
|
|
-- } else {
|
|
|
-- sym = 0;
|
|
|
-- def.sym = 0;
|
|
|
-- def.dso = dso;
|
|
|
-- }
|
|
|
--
|
|
|
-- if (stride > 2) {
|
|
|
-- addend = rel[2];
|
|
|
-- } else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) {
|
|
|
-- addend = 0;
|
|
|
-- } else if (reuse_addends) {
|
|
|
-- /* Save original addend in stage 2 where the dso
|
|
|
-- * chain consists of just ldso; otherwise read back
|
|
|
-- * saved addend since the inline one was clobbered. */
|
|
|
-- if (head==&ldso)
|
|
|
-- saved_addends[save_slot] = *reloc_addr;
|
|
|
-- addend = saved_addends[save_slot++];
|
|
|
-- } else {
|
|
|
-- addend = *reloc_addr;
|
|
|
-- }
|
|
|
--
|
|
|
-- sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0;
|
|
|
-- tls_val = def.sym ? def.sym->st_value : 0;
|
|
|
--
|
|
|
-- switch(type) {
|
|
|
-- case REL_NONE:
|
|
|
-- break;
|
|
|
-- case REL_OFFSET:
|
|
|
-- addend -= (size_t)reloc_addr;
|
|
|
-- case REL_SYMBOLIC:
|
|
|
-- case REL_GOT:
|
|
|
-- case REL_PLT:
|
|
|
-- *reloc_addr = sym_val + addend;
|
|
|
-- break;
|
|
|
-- case REL_RELATIVE:
|
|
|
-- *reloc_addr = (size_t)base + addend;
|
|
|
-- break;
|
|
|
-- case REL_SYM_OR_REL:
|
|
|
-- if (sym) *reloc_addr = sym_val + addend;
|
|
|
-- else *reloc_addr = (size_t)base + addend;
|
|
|
-- break;
|
|
|
-- case REL_COPY:
|
|
|
-- memcpy(reloc_addr, (void *)sym_val, sym->st_size);
|
|
|
-- break;
|
|
|
-- case REL_OFFSET32:
|
|
|
-- *(uint32_t *)reloc_addr = sym_val + addend
|
|
|
-- - (size_t)reloc_addr;
|
|
|
-- break;
|
|
|
-- case REL_FUNCDESC:
|
|
|
-- *reloc_addr = def.sym ? (size_t)(def.dso->funcdescs
|
|
|
-- + (def.sym - def.dso->syms)) : 0;
|
|
|
-- break;
|
|
|
-- case REL_FUNCDESC_VAL:
|
|
|
-- if ((sym->st_info&0xf) == STT_SECTION) *reloc_addr += sym_val;
|
|
|
-- else *reloc_addr = sym_val;
|
|
|
-- reloc_addr[1] = def.sym ? (size_t)def.dso->got : 0;
|
|
|
-- break;
|
|
|
-- case REL_DTPMOD:
|
|
|
-- *reloc_addr = def.dso->tls_id;
|
|
|
-- break;
|
|
|
-- case REL_DTPOFF:
|
|
|
-- *reloc_addr = tls_val + addend - DTP_OFFSET;
|
|
|
-- break;
|
|
|
--#ifdef TLS_ABOVE_TP
|
|
|
-- case REL_TPOFF:
|
|
|
-- *reloc_addr = tls_val + def.dso->tls_offset + TPOFF_K + addend;
|
|
|
-- break;
|
|
|
--#else
|
|
|
-- case REL_TPOFF:
|
|
|
-- *reloc_addr = tls_val - def.dso->tls_offset + addend;
|
|
|
-- break;
|
|
|
-- case REL_TPOFF_NEG:
|
|
|
-- *reloc_addr = def.dso->tls_offset - tls_val + addend;
|
|
|
-- break;
|
|
|
--#endif
|
|
|
-- case REL_TLSDESC:
|
|
|
-- if (stride<3) addend = reloc_addr[1];
|
|
|
-- if (runtime && def.dso->tls_id >= static_tls_cnt) {
|
|
|
-- struct td_index *new = malloc(sizeof *new);
|
|
|
-- if (!new) {
|
|
|
-- error(
|
|
|
-- "Error relocating %s: cannot allocate TLSDESC for %s",
|
|
|
-- dso->name, sym ? name : "(local)" );
|
|
|
-- longjmp(*rtld_fail, 1);
|
|
|
-- }
|
|
|
-- new->next = dso->td_index;
|
|
|
-- dso->td_index = new;
|
|
|
-- new->args[0] = def.dso->tls_id;
|
|
|
-- new->args[1] = tls_val + addend;
|
|
|
-- reloc_addr[0] = (size_t)__tlsdesc_dynamic;
|
|
|
-- reloc_addr[1] = (size_t)new;
|
|
|
-- } else {
|
|
|
-- reloc_addr[0] = (size_t)__tlsdesc_static;
|
|
|
--#ifdef TLS_ABOVE_TP
|
|
|
-- reloc_addr[1] = tls_val + def.dso->tls_offset
|
|
|
-- + TPOFF_K + addend;
|
|
|
--#else
|
|
|
-- reloc_addr[1] = tls_val - def.dso->tls_offset
|
|
|
-- + addend;
|
|
|
--#endif
|
|
|
-- }
|
|
|
-- break;
|
|
|
-- default:
|
|
|
-- error("Error relocating %s: unsupported relocation type %d",
|
|
|
-- dso->name, type);
|
|
|
-- if (runtime) longjmp(*rtld_fail, 1);
|
|
|
-- continue;
|
|
|
-- }
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--/* A huge hack: to make up for the wastefulness of shared libraries
|
|
|
-- * needing at least a page of dirty memory even if they have no global
|
|
|
-- * data, we reclaim the gaps at the beginning and end of writable maps
|
|
|
-- * and "donate" them to the heap by setting up minimal malloc
|
|
|
-- * structures and then freeing them. */
|
|
|
--
|
|
|
--static void reclaim(struct dso *dso, size_t start, size_t end)
|
|
|
--{
|
|
|
-- size_t *a, *z;
|
|
|
-- if (start >= dso->relro_start && start < dso->relro_end) start = dso->relro_end;
|
|
|
-- if (end >= dso->relro_start && end < dso->relro_end) end = dso->relro_start;
|
|
|
-- start = start + 6*sizeof(size_t)-1 & -4*sizeof(size_t);
|
|
|
-- end = (end & -4*sizeof(size_t)) - 2*sizeof(size_t);
|
|
|
-- if (start>end || end-start < 4*sizeof(size_t)) return;
|
|
|
-- a = laddr(dso, start);
|
|
|
-- z = laddr(dso, end);
|
|
|
-- a[-2] = 1;
|
|
|
-- a[-1] = z[0] = end-start + 2*sizeof(size_t) | 1;
|
|
|
-- z[1] = 1;
|
|
|
-- free(a);
|
|
|
--}
|
|
|
--
|
|
|
--static void reclaim_gaps(struct dso *dso)
|
|
|
--{
|
|
|
-- Phdr *ph = dso->phdr;
|
|
|
-- size_t phcnt = dso->phnum;
|
|
|
--
|
|
|
-- if (DL_FDPIC) return; // FIXME
|
|
|
-- for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) {
|
|
|
-- if (ph->p_type!=PT_LOAD) continue;
|
|
|
-- if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue;
|
|
|
-- reclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr);
|
|
|
-- reclaim(dso, ph->p_vaddr+ph->p_memsz,
|
|
|
-- ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE);
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
|
|
|
--{
|
|
|
-- char *q = mmap(p, n, prot, flags, fd, off);
|
|
|
-- if (q != MAP_FAILED || errno != EINVAL) return q;
|
|
|
-- /* Fallbacks for MAP_FIXED failure on NOMMU kernels. */
|
|
|
-- if (flags & MAP_ANONYMOUS) {
|
|
|
-- memset(p, 0, n);
|
|
|
-- return p;
|
|
|
-- }
|
|
|
-- ssize_t r;
|
|
|
-- if (lseek(fd, off, SEEK_SET) < 0) return MAP_FAILED;
|
|
|
-- for (q=p; n; q+=r, off+=r, n-=r) {
|
|
|
-- r = read(fd, q, n);
|
|
|
-- if (r < 0 && errno != EINTR) return MAP_FAILED;
|
|
|
-- if (!r) {
|
|
|
-- memset(q, 0, n);
|
|
|
-- break;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- return p;
|
|
|
--}
|
|
|
--
|
|
|
--static void unmap_library(struct dso *dso)
|
|
|
--{
|
|
|
-- if (dso->loadmap) {
|
|
|
-- size_t i;
|
|
|
-- for (i=0; i<dso->loadmap->nsegs; i++) {
|
|
|
-- if (!dso->loadmap->segs[i].p_memsz)
|
|
|
-- continue;
|
|
|
-- munmap((void *)dso->loadmap->segs[i].addr,
|
|
|
-- dso->loadmap->segs[i].p_memsz);
|
|
|
-- }
|
|
|
-- free(dso->loadmap);
|
|
|
-- } else if (dso->map && dso->map_len) {
|
|
|
-- munmap(dso->map, dso->map_len);
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--static void *map_library(int fd, struct dso *dso)
|
|
|
--{
|
|
|
-- Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
|
|
|
-- void *allocated_buf=0;
|
|
|
-- size_t phsize;
|
|
|
-- size_t addr_min=SIZE_MAX, addr_max=0, map_len;
|
|
|
-- size_t this_min, this_max;
|
|
|
-- size_t nsegs = 0;
|
|
|
-- off_t off_start;
|
|
|
-- Ehdr *eh;
|
|
|
-- Phdr *ph, *ph0;
|
|
|
-- unsigned prot;
|
|
|
-- unsigned char *map=MAP_FAILED, *base;
|
|
|
-- size_t dyn=0;
|
|
|
-- size_t tls_image=0;
|
|
|
-- size_t i;
|
|
|
--
|
|
|
-- ssize_t l = read(fd, buf, sizeof buf);
|
|
|
-- eh = buf;
|
|
|
-- if (l<0) return 0;
|
|
|
-- if (l<sizeof *eh || (eh->e_type != ET_DYN && eh->e_type != ET_EXEC))
|
|
|
-- goto noexec;
|
|
|
-- phsize = eh->e_phentsize * eh->e_phnum;
|
|
|
-- if (phsize > sizeof buf - sizeof *eh) {
|
|
|
-- allocated_buf = malloc(phsize);
|
|
|
-- if (!allocated_buf) return 0;
|
|
|
-- l = pread(fd, allocated_buf, phsize, eh->e_phoff);
|
|
|
-- if (l < 0) goto error;
|
|
|
-- if (l != phsize) goto noexec;
|
|
|
-- ph = ph0 = allocated_buf;
|
|
|
-- } else if (eh->e_phoff + phsize > l) {
|
|
|
-- l = pread(fd, buf+1, phsize, eh->e_phoff);
|
|
|
-- if (l < 0) goto error;
|
|
|
-- if (l != phsize) goto noexec;
|
|
|
-- ph = ph0 = (void *)(buf + 1);
|
|
|
-- } else {
|
|
|
-- ph = ph0 = (void *)((char *)buf + eh->e_phoff);
|
|
|
-- }
|
|
|
-- for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
|
|
|
-- if (ph->p_type == PT_DYNAMIC) {
|
|
|
-- dyn = ph->p_vaddr;
|
|
|
-- } else if (ph->p_type == PT_TLS) {
|
|
|
-- tls_image = ph->p_vaddr;
|
|
|
-- dso->tls_align = ph->p_align;
|
|
|
-- dso->tls_len = ph->p_filesz;
|
|
|
-- dso->tls_size = ph->p_memsz;
|
|
|
-- } else if (ph->p_type == PT_GNU_RELRO) {
|
|
|
-- dso->relro_start = ph->p_vaddr & -PAGE_SIZE;
|
|
|
-- dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
|
|
|
-- }
|
|
|
-- if (ph->p_type != PT_LOAD) continue;
|
|
|
-- nsegs++;
|
|
|
-- if (ph->p_vaddr < addr_min) {
|
|
|
-- addr_min = ph->p_vaddr;
|
|
|
-- off_start = ph->p_offset;
|
|
|
-- prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
|
|
|
-- ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
|
|
|
-- ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
|
|
|
-- }
|
|
|
-- if (ph->p_vaddr+ph->p_memsz > addr_max) {
|
|
|
-- addr_max = ph->p_vaddr+ph->p_memsz;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- if (!dyn) goto noexec;
|
|
|
-- if (DL_FDPIC && !(eh->e_flags & FDPIC_CONSTDISP_FLAG)) {
|
|
|
-- dso->loadmap = calloc(1, sizeof *dso->loadmap
|
|
|
-- + nsegs * sizeof *dso->loadmap->segs);
|
|
|
-- if (!dso->loadmap) goto error;
|
|
|
-- dso->loadmap->nsegs = nsegs;
|
|
|
-- for (ph=ph0, i=0; i<nsegs; ph=(void *)((char *)ph+eh->e_phentsize)) {
|
|
|
-- if (ph->p_type != PT_LOAD) continue;
|
|
|
-- prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
|
|
|
-- ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
|
|
|
-- ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
|
|
|
-- map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1),
|
|
|
-- prot, (prot&PROT_WRITE) ? MAP_PRIVATE : MAP_SHARED,
|
|
|
-- fd, ph->p_offset & -PAGE_SIZE);
|
|
|
-- if (map == MAP_FAILED) {
|
|
|
-- unmap_library(dso);
|
|
|
-- goto error;
|
|
|
-- }
|
|
|
-- dso->loadmap->segs[i].addr = (size_t)map +
|
|
|
-- (ph->p_vaddr & PAGE_SIZE-1);
|
|
|
-- dso->loadmap->segs[i].p_vaddr = ph->p_vaddr;
|
|
|
-- dso->loadmap->segs[i].p_memsz = ph->p_memsz;
|
|
|
-- i++;
|
|
|
-- }
|
|
|
-- map = (void *)dso->loadmap->segs[0].addr;
|
|
|
-- map_len = 0;
|
|
|
-- goto done_mapping;
|
|
|
-- }
|
|
|
-- addr_max += PAGE_SIZE-1;
|
|
|
-- addr_max &= -PAGE_SIZE;
|
|
|
-- addr_min &= -PAGE_SIZE;
|
|
|
-- off_start &= -PAGE_SIZE;
|
|
|
-- map_len = addr_max - addr_min + off_start;
|
|
|
-- /* The first time, we map too much, possibly even more than
|
|
|
-- * the length of the file. This is okay because we will not
|
|
|
-- * use the invalid part; we just need to reserve the right
|
|
|
-- * amount of virtual address space to map over later. */
|
|
|
-- map = mmap((void *)addr_min, map_len, prot, MAP_PRIVATE, fd, off_start);
|
|
|
-- if (map==MAP_FAILED) goto error;
|
|
|
-- dso->map = map;
|
|
|
-- dso->map_len = map_len;
|
|
|
-- /* If the loaded file is not relocatable and the requested address is
|
|
|
-- * not available, then the load operation must fail. */
|
|
|
-- if (eh->e_type != ET_DYN && addr_min && map!=(void *)addr_min) {
|
|
|
-- errno = EBUSY;
|
|
|
-- goto error;
|
|
|
-- }
|
|
|
-- base = map - addr_min;
|
|
|
-- dso->phdr = 0;
|
|
|
-- dso->phnum = 0;
|
|
|
-- for (ph=ph0, i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
|
|
|
-- if (ph->p_type != PT_LOAD) continue;
|
|
|
-- /* Check if the programs headers are in this load segment, and
|
|
|
-- * if so, record the address for use by dl_iterate_phdr. */
|
|
|
-- if (!dso->phdr && eh->e_phoff >= ph->p_offset
|
|
|
-- && eh->e_phoff+phsize <= ph->p_offset+ph->p_filesz) {
|
|
|
-- dso->phdr = (void *)(base + ph->p_vaddr
|
|
|
-- + (eh->e_phoff-ph->p_offset));
|
|
|
-- dso->phnum = eh->e_phnum;
|
|
|
-- dso->phentsize = eh->e_phentsize;
|
|
|
-- }
|
|
|
-- /* Reuse the existing mapping for the lowest-address LOAD */
|
|
|
-- if ((ph->p_vaddr & -PAGE_SIZE) == addr_min) continue;
|
|
|
-- this_min = ph->p_vaddr & -PAGE_SIZE;
|
|
|
-- this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;
|
|
|
-- off_start = ph->p_offset & -PAGE_SIZE;
|
|
|
-- prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
|
|
|
-- ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
|
|
|
-- ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
|
|
|
-- if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
|
|
|
-- goto error;
|
|
|
-- if (ph->p_memsz > ph->p_filesz) {
|
|
|
-- size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
|
|
|
-- size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
|
|
|
-- memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
|
|
|
-- if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
|
|
|
-- goto error;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
|
|
|
-- if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
|
|
|
-- if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC)
|
|
|
-- && errno != ENOSYS)
|
|
|
-- goto error;
|
|
|
-- break;
|
|
|
-- }
|
|
|
--done_mapping:
|
|
|
-- dso->base = base;
|
|
|
-- dso->dynv = laddr(dso, dyn);
|
|
|
-- if (dso->tls_size) dso->tls_image = laddr(dso, tls_image);
|
|
|
-- if (!runtime) reclaim_gaps(dso);
|
|
|
-- free(allocated_buf);
|
|
|
-- return map;
|
|
|
--noexec:
|
|
|
-- errno = ENOEXEC;
|
|
|
--error:
|
|
|
-- if (map!=MAP_FAILED) unmap_library(dso);
|
|
|
-- free(allocated_buf);
|
|
|
-- return 0;
|
|
|
--}
|
|
|
--
|
|
|
--static int path_open(const char *name, const char *s, char *buf, size_t buf_size)
|
|
|
--{
|
|
|
-- size_t l;
|
|
|
-- int fd;
|
|
|
-- for (;;) {
|
|
|
-- s += strspn(s, ":\n");
|
|
|
-- l = strcspn(s, ":\n");
|
|
|
-- if (l-1 >= INT_MAX) return -1;
|
|
|
-- if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) {
|
|
|
-- if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd;
|
|
|
-- switch (errno) {
|
|
|
-- case ENOENT:
|
|
|
-- case ENOTDIR:
|
|
|
-- case EACCES:
|
|
|
-- case ENAMETOOLONG:
|
|
|
-- break;
|
|
|
-- default:
|
|
|
-- /* Any negative value but -1 will inhibit
|
|
|
-- * futher path search. */
|
|
|
-- return -2;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- s += l;
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)
|
|
|
--{
|
|
|
-- size_t n, l;
|
|
|
-- const char *s, *t, *origin;
|
|
|
-- char *d;
|
|
|
-- if (p->rpath || !p->rpath_orig) return 0;
|
|
|
-- if (!strchr(p->rpath_orig, '$')) {
|
|
|
-- p->rpath = p->rpath_orig;
|
|
|
-- return 0;
|
|
|
-- }
|
|
|
-- n = 0;
|
|
|
-- s = p->rpath_orig;
|
|
|
-- while ((t=strchr(s, '$'))) {
|
|
|
-- if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9))
|
|
|
-- return 0;
|
|
|
-- s = t+1;
|
|
|
-- n++;
|
|
|
-- }
|
|
|
-- if (n > SSIZE_MAX/PATH_MAX) return 0;
|
|
|
--
|
|
|
-- if (p->kernel_mapped) {
|
|
|
-- /* $ORIGIN searches cannot be performed for the main program
|
|
|
-- * when it is suid/sgid/AT_SECURE. This is because the
|
|
|
-- * pathname is under the control of the caller of execve.
|
|
|
-- * For libraries, however, $ORIGIN can be processed safely
|
|
|
-- * since the library's pathname came from a trusted source
|
|
|
-- * (either system paths or a call to dlopen). */
|
|
|
-- if (libc.secure)
|
|
|
-- return 0;
|
|
|
-- l = readlink("/proc/self/exe", buf, buf_size);
|
|
|
-- if (l == -1) switch (errno) {
|
|
|
-- case ENOENT:
|
|
|
-- case ENOTDIR:
|
|
|
-- case EACCES:
|
|
|
-- break;
|
|
|
-- default:
|
|
|
-- return -1;
|
|
|
-- }
|
|
|
-- if (l >= buf_size)
|
|
|
-- return 0;
|
|
|
-- buf[l] = 0;
|
|
|
-- origin = buf;
|
|
|
-- } else {
|
|
|
-- origin = p->name;
|
|
|
-- }
|
|
|
-- t = strrchr(origin, '/');
|
|
|
-- l = t ? t-origin : 0;
|
|
|
-- p->rpath = malloc(strlen(p->rpath_orig) + n*l + 1);
|
|
|
-- if (!p->rpath) return -1;
|
|
|
--
|
|
|
-- d = p->rpath;
|
|
|
-- s = p->rpath_orig;
|
|
|
-- while ((t=strchr(s, '$'))) {
|
|
|
-- memcpy(d, s, t-s);
|
|
|
-- d += t-s;
|
|
|
-- memcpy(d, origin, l);
|
|
|
-- d += l;
|
|
|
-- /* It was determined previously that the '$' is followed
|
|
|
-- * either by "ORIGIN" or "{ORIGIN}". */
|
|
|
-- s = t + 7 + 2*(t[1]=='{');
|
|
|
-- }
|
|
|
-- strcpy(d, s);
|
|
|
-- return 0;
|
|
|
--}
|
|
|
--
|
|
|
--static void decode_dyn(struct dso *p)
|
|
|
--{
|
|
|
-- size_t dyn[DYN_CNT];
|
|
|
-- decode_vec(p->dynv, dyn, DYN_CNT);
|
|
|
-- p->syms = laddr(p, dyn[DT_SYMTAB]);
|
|
|
-- p->strings = laddr(p, dyn[DT_STRTAB]);
|
|
|
-- if (dyn[0]&(1<<DT_HASH))
|
|
|
-- p->hashtab = laddr(p, dyn[DT_HASH]);
|
|
|
-- if (dyn[0]&(1<<DT_RPATH))
|
|
|
-- p->rpath_orig = p->strings + dyn[DT_RPATH];
|
|
|
-- if (dyn[0]&(1<<DT_RUNPATH))
|
|
|
-- p->rpath_orig = p->strings + dyn[DT_RUNPATH];
|
|
|
-- if (dyn[0]&(1<<DT_PLTGOT))
|
|
|
-- p->got = laddr(p, dyn[DT_PLTGOT]);
|
|
|
-- if (search_vec(p->dynv, dyn, DT_GNU_HASH))
|
|
|
-- p->ghashtab = laddr(p, *dyn);
|
|
|
-- if (search_vec(p->dynv, dyn, DT_VERSYM))
|
|
|
-- p->versym = laddr(p, *dyn);
|
|
|
--}
|
|
|
--
|
|
|
--static size_t count_syms(struct dso *p)
|
|
|
--{
|
|
|
-- if (p->hashtab) return p->hashtab[1];
|
|
|
--
|
|
|
-- size_t nsym, i;
|
|
|
-- uint32_t *buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4);
|
|
|
-- uint32_t *hashval;
|
|
|
-- for (i = nsym = 0; i < p->ghashtab[0]; i++) {
|
|
|
-- if (buckets[i] > nsym)
|
|
|
-- nsym = buckets[i];
|
|
|
-- }
|
|
|
-- if (nsym) {
|
|
|
-- hashval = buckets + p->ghashtab[0] + (nsym - p->ghashtab[1]);
|
|
|
-- do nsym++;
|
|
|
-- while (!(*hashval++ & 1));
|
|
|
-- }
|
|
|
-- return nsym;
|
|
|
--}
|
|
|
--
|
|
|
--static void *dl_mmap(size_t n)
|
|
|
--{
|
|
|
-- void *p;
|
|
|
-- int prot = PROT_READ|PROT_WRITE, flags = MAP_ANONYMOUS|MAP_PRIVATE;
|
|
|
--#ifdef SYS_mmap2
|
|
|
-- p = (void *)__syscall(SYS_mmap2, 0, n, prot, flags, -1, 0);
|
|
|
--#else
|
|
|
-- p = (void *)__syscall(SYS_mmap, 0, n, prot, flags, -1, 0);
|
|
|
--#endif
|
|
|
-- return p == MAP_FAILED ? 0 : p;
|
|
|
--}
|
|
|
--
|
|
|
--static void makefuncdescs(struct dso *p)
|
|
|
--{
|
|
|
-- static int self_done;
|
|
|
-- size_t nsym = count_syms(p);
|
|
|
-- size_t i, size = nsym * sizeof(*p->funcdescs);
|
|
|
--
|
|
|
-- if (!self_done) {
|
|
|
-- p->funcdescs = dl_mmap(size);
|
|
|
-- self_done = 1;
|
|
|
-- } else {
|
|
|
-- p->funcdescs = malloc(size);
|
|
|
-- }
|
|
|
-- if (!p->funcdescs) {
|
|
|
-- if (!runtime) a_crash();
|
|
|
-- error("Error allocating function descriptors for %s", p->name);
|
|
|
-- longjmp(*rtld_fail, 1);
|
|
|
-- }
|
|
|
-- for (i=0; i<nsym; i++) {
|
|
|
-- if ((p->syms[i].st_info&0xf)==STT_FUNC && p->syms[i].st_shndx) {
|
|
|
-- p->funcdescs[i].addr = laddr(p, p->syms[i].st_value);
|
|
|
-- p->funcdescs[i].got = p->got;
|
|
|
-- } else {
|
|
|
-- p->funcdescs[i].addr = 0;
|
|
|
-- p->funcdescs[i].got = 0;
|
|
|
-- }
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--static struct dso *load_library(const char *name, struct dso *needed_by)
|
|
|
--{
|
|
|
-- char buf[2*NAME_MAX+2];
|
|
|
-- const char *pathname;
|
|
|
-- unsigned char *map;
|
|
|
-- struct dso *p, temp_dso = {0};
|
|
|
-- int fd;
|
|
|
-- struct stat st;
|
|
|
-- size_t alloc_size;
|
|
|
-- int n_th = 0;
|
|
|
-- int is_self = 0;
|
|
|
--
|
|
|
-- if (!*name) {
|
|
|
-- errno = EINVAL;
|
|
|
-- return 0;
|
|
|
-- }
|
|
|
--
|
|
|
-- /* Catch and block attempts to reload the implementation itself */
|
|
|
-- if (name[0]=='l' && name[1]=='i' && name[2]=='b') {
|
|
|
-- static const char *rp, reserved[] =
|
|
|
-- "c\0pthread\0rt\0m\0dl\0util\0xnet\0";
|
|
|
-- char *z = strchr(name, '.');
|
|
|
-- if (z) {
|
|
|
-- size_t l = z-name;
|
|
|
-- for (rp=reserved; *rp && strncmp(name+3, rp, l-3); rp+=strlen(rp)+1);
|
|
|
-- if (*rp) {
|
|
|
-- if (ldd_mode) {
|
|
|
-- /* Track which names have been resolved
|
|
|
-- * and only report each one once. */
|
|
|
-- static unsigned reported;
|
|
|
-- unsigned mask = 1U<<(rp-reserved);
|
|
|
-- if (!(reported & mask)) {
|
|
|
-- reported |= mask;
|
|
|
-- dprintf(1, "\t%s => %s (%p)\n",
|
|
|
-- name, ldso.name,
|
|
|
-- ldso.base);
|
|
|
-- }
|
|
|
-- }
|
|
|
-- is_self = 1;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- }
|
|
|
-- if (!strcmp(name, ldso.name)) is_self = 1;
|
|
|
-- if (is_self) {
|
|
|
-- if (!ldso.prev) {
|
|
|
-- tail->next = &ldso;
|
|
|
-- ldso.prev = tail;
|
|
|
-- tail = ldso.next ? ldso.next : &ldso;
|
|
|
-- }
|
|
|
-- return &ldso;
|
|
|
-- }
|
|
|
-- if (strchr(name, '/')) {
|
|
|
-- pathname = name;
|
|
|
-- fd = open(name, O_RDONLY|O_CLOEXEC);
|
|
|
-- } else {
|
|
|
-- /* Search for the name to see if it's already loaded */
|
|
|
-- for (p=head->next; p; p=p->next) {
|
|
|
-- if (p->shortname && !strcmp(p->shortname, name)) {
|
|
|
-- p->refcnt++;
|
|
|
-- return p;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- if (strlen(name) > NAME_MAX) return 0;
|
|
|
-- fd = -1;
|
|
|
-- if (env_path) fd = path_open(name, env_path, buf, sizeof buf);
|
|
|
-- for (p=needed_by; fd == -1 && p; p=p->needed_by) {
|
|
|
-- if (fixup_rpath(p, buf, sizeof buf) < 0)
|
|
|
-- fd = -2; /* Inhibit further search. */
|
|
|
-- if (p->rpath)
|
|
|
-- fd = path_open(name, p->rpath, buf, sizeof buf);
|
|
|
-- }
|
|
|
-- if (fd == -1) {
|
|
|
-- if (!sys_path) {
|
|
|
-- char *prefix = 0;
|
|
|
-- size_t prefix_len;
|
|
|
-- if (ldso.name[0]=='/') {
|
|
|
-- char *s, *t, *z;
|
|
|
-- for (s=t=z=ldso.name; *s; s++)
|
|
|
-- if (*s=='/') z=t, t=s;
|
|
|
-- prefix_len = z-ldso.name;
|
|
|
-- if (prefix_len < PATH_MAX)
|
|
|
-- prefix = ldso.name;
|
|
|
-- }
|
|
|
-- if (!prefix) {
|
|
|
-- prefix = "";
|
|
|
-- prefix_len = 0;
|
|
|
-- }
|
|
|
-- char etc_ldso_path[prefix_len + 1
|
|
|
-- + sizeof "/etc/ld-musl-" LDSO_ARCH ".path"];
|
|
|
-- snprintf(etc_ldso_path, sizeof etc_ldso_path,
|
|
|
-- "%.*s/etc/ld-musl-" LDSO_ARCH ".path",
|
|
|
-- (int)prefix_len, prefix);
|
|
|
-- FILE *f = fopen(etc_ldso_path, "rbe");
|
|
|
-- if (f) {
|
|
|
-- if (getdelim(&sys_path, (size_t[1]){0}, 0, f) <= 0) {
|
|
|
-- free(sys_path);
|
|
|
-- sys_path = "";
|
|
|
-- }
|
|
|
-- fclose(f);
|
|
|
-- } else if (errno != ENOENT) {
|
|
|
-- sys_path = "";
|
|
|
-- }
|
|
|
-- }
|
|
|
-- if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";
|
|
|
-- fd = path_open(name, sys_path, buf, sizeof buf);
|
|
|
-- }
|
|
|
-- pathname = buf;
|
|
|
-- }
|
|
|
-- if (fd < 0) return 0;
|
|
|
-- if (fstat(fd, &st) < 0) {
|
|
|
-- close(fd);
|
|
|
-- return 0;
|
|
|
-- }
|
|
|
-- for (p=head->next; p; p=p->next) {
|
|
|
-- if (p->dev == st.st_dev && p->ino == st.st_ino) {
|
|
|
-- /* If this library was previously loaded with a
|
|
|
-- * pathname but a search found the same inode,
|
|
|
-- * setup its shortname so it can be found by name. */
|
|
|
-- if (!p->shortname && pathname != name)
|
|
|
-- p->shortname = strrchr(p->name, '/')+1;
|
|
|
-- close(fd);
|
|
|
-- p->refcnt++;
|
|
|
-- return p;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- map = noload ? 0 : map_library(fd, &temp_dso);
|
|
|
-- close(fd);
|
|
|
-- if (!map) return 0;
|
|
|
--
|
|
|
-- /* Allocate storage for the new DSO. When there is TLS, this
|
|
|
-- * storage must include a reservation for all pre-existing
|
|
|
-- * threads to obtain copies of both the new TLS, and an
|
|
|
-- * extended DTV capable of storing an additional slot for
|
|
|
-- * the newly-loaded DSO. */
|
|
|
-- alloc_size = sizeof *p + strlen(pathname) + 1;
|
|
|
-- if (runtime && temp_dso.tls_image) {
|
|
|
-- size_t per_th = temp_dso.tls_size + temp_dso.tls_align
|
|
|
-- + sizeof(void *) * (tls_cnt+3);
|
|
|
-- n_th = libc.threads_minus_1 + 1;
|
|
|
-- if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX;
|
|
|
-- else alloc_size += n_th * per_th;
|
|
|
-- }
|
|
|
-- p = calloc(1, alloc_size);
|
|
|
-- if (!p) {
|
|
|
-- unmap_library(&temp_dso);
|
|
|
-- return 0;
|
|
|
-- }
|
|
|
-- memcpy(p, &temp_dso, sizeof temp_dso);
|
|
|
-- decode_dyn(p);
|
|
|
-- p->dev = st.st_dev;
|
|
|
-- p->ino = st.st_ino;
|
|
|
-- p->refcnt = 1;
|
|
|
-- p->needed_by = needed_by;
|
|
|
-- p->name = p->buf;
|
|
|
-- strcpy(p->name, pathname);
|
|
|
-- /* Add a shortname only if name arg was not an explicit pathname. */
|
|
|
-- if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
|
|
|
-- if (p->tls_image) {
|
|
|
-- p->tls_id = ++tls_cnt;
|
|
|
-- tls_align = MAXP2(tls_align, p->tls_align);
|
|
|
--#ifdef TLS_ABOVE_TP
|
|
|
-- p->tls_offset = tls_offset + ( (tls_align-1) &
|
|
|
-- -(tls_offset + (uintptr_t)p->tls_image) );
|
|
|
-- tls_offset += p->tls_size;
|
|
|
--#else
|
|
|
-- tls_offset += p->tls_size + p->tls_align - 1;
|
|
|
-- tls_offset -= (tls_offset + (uintptr_t)p->tls_image)
|
|
|
-- & (p->tls_align-1);
|
|
|
-- p->tls_offset = tls_offset;
|
|
|
--#endif
|
|
|
-- p->new_dtv = (void *)(-sizeof(size_t) &
|
|
|
-- (uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));
|
|
|
-- p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));
|
|
|
-- }
|
|
|
--
|
|
|
-- tail->next = p;
|
|
|
-- p->prev = tail;
|
|
|
-- tail = p;
|
|
|
--
|
|
|
-- if (DL_FDPIC) makefuncdescs(p);
|
|
|
--
|
|
|
-- if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base);
|
|
|
--
|
|
|
-- return p;
|
|
|
--}
|
|
|
--
|
|
|
--static void load_deps(struct dso *p)
|
|
|
--{
|
|
|
-- size_t i, ndeps=0;
|
|
|
-- struct dso ***deps = &p->deps, **tmp, *dep;
|
|
|
-- for (; p; p=p->next) {
|
|
|
-- for (i=0; p->dynv[i]; i+=2) {
|
|
|
-- if (p->dynv[i] != DT_NEEDED) continue;
|
|
|
-- dep = load_library(p->strings + p->dynv[i+1], p);
|
|
|
-- if (!dep) {
|
|
|
-- error("Error loading shared library %s: %m (needed by %s)",
|
|
|
-- p->strings + p->dynv[i+1], p->name);
|
|
|
-- if (runtime) longjmp(*rtld_fail, 1);
|
|
|
-- continue;
|
|
|
-- }
|
|
|
-- if (runtime) {
|
|
|
-- tmp = realloc(*deps, sizeof(*tmp)*(ndeps+2));
|
|
|
-- if (!tmp) longjmp(*rtld_fail, 1);
|
|
|
-- tmp[ndeps++] = dep;
|
|
|
-- tmp[ndeps] = 0;
|
|
|
-- *deps = tmp;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--static void load_preload(char *s)
|
|
|
--{
|
|
|
-- int tmp;
|
|
|
-- char *z;
|
|
|
-- for (z=s; *z; s=z) {
|
|
|
-- for ( ; *s && (isspace(*s) || *s==':'); s++);
|
|
|
-- for (z=s; *z && !isspace(*z) && *z!=':'; z++);
|
|
|
-- tmp = *z;
|
|
|
-- *z = 0;
|
|
|
-- load_library(s, 0);
|
|
|
-- *z = tmp;
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--static void make_global(struct dso *p)
|
|
|
--{
|
|
|
-- for (; p; p=p->next) p->global = 1;
|
|
|
--}
|
|
|
--
|
|
|
--static void do_mips_relocs(struct dso *p, size_t *got)
|
|
|
--{
|
|
|
-- size_t i, j, rel[2];
|
|
|
-- unsigned char *base = p->base;
|
|
|
-- i=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO);
|
|
|
-- if (p==&ldso) {
|
|
|
-- got += i;
|
|
|
-- } else {
|
|
|
-- while (i--) *got++ += (size_t)base;
|
|
|
-- }
|
|
|
-- j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);
|
|
|
-- i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);
|
|
|
-- Sym *sym = p->syms + j;
|
|
|
-- rel[0] = (unsigned char *)got - base;
|
|
|
-- for (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) {
|
|
|
-- rel[1] = sym-p->syms << 8 | R_MIPS_JUMP_SLOT;
|
|
|
-- do_relocs(p, rel, sizeof rel, 2);
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--static void reloc_all(struct dso *p)
|
|
|
--{
|
|
|
-- size_t dyn[DYN_CNT];
|
|
|
-- for (; p; p=p->next) {
|
|
|
-- if (p->relocated) continue;
|
|
|
-- decode_vec(p->dynv, dyn, DYN_CNT);
|
|
|
-- if (NEED_MIPS_GOT_RELOCS)
|
|
|
-- do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT]));
|
|
|
-- do_relocs(p, laddr(p, dyn[DT_JMPREL]), dyn[DT_PLTRELSZ],
|
|
|
-- 2+(dyn[DT_PLTREL]==DT_RELA));
|
|
|
-- do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2);
|
|
|
-- do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3);
|
|
|
--
|
|
|
-- if (head != &ldso && p->relro_start != p->relro_end &&
|
|
|
-- mprotect(laddr(p, p->relro_start), p->relro_end-p->relro_start, PROT_READ)
|
|
|
-- && errno != ENOSYS) {
|
|
|
-- error("Error relocating %s: RELRO protection failed: %m",
|
|
|
-- p->name);
|
|
|
-- if (runtime) longjmp(*rtld_fail, 1);
|
|
|
-- }
|
|
|
--
|
|
|
-- p->relocated = 1;
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--static void kernel_mapped_dso(struct dso *p)
|
|
|
--{
|
|
|
-- size_t min_addr = -1, max_addr = 0, cnt;
|
|
|
-- Phdr *ph = p->phdr;
|
|
|
-- for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) {
|
|
|
-- if (ph->p_type == PT_DYNAMIC) {
|
|
|
-- p->dynv = laddr(p, ph->p_vaddr);
|
|
|
-- } else if (ph->p_type == PT_GNU_RELRO) {
|
|
|
-- p->relro_start = ph->p_vaddr & -PAGE_SIZE;
|
|
|
-- p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
|
|
|
-- }
|
|
|
-- if (ph->p_type != PT_LOAD) continue;
|
|
|
-- if (ph->p_vaddr < min_addr)
|
|
|
-- min_addr = ph->p_vaddr;
|
|
|
-- if (ph->p_vaddr+ph->p_memsz > max_addr)
|
|
|
-- max_addr = ph->p_vaddr+ph->p_memsz;
|
|
|
-- }
|
|
|
-- min_addr &= -PAGE_SIZE;
|
|
|
-- max_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE;
|
|
|
-- p->map = p->base + min_addr;
|
|
|
-- p->map_len = max_addr - min_addr;
|
|
|
-- p->kernel_mapped = 1;
|
|
|
--}
|
|
|
--
|
|
|
--static void do_fini()
|
|
|
--{
|
|
|
-- struct dso *p;
|
|
|
-- size_t dyn[DYN_CNT];
|
|
|
-- for (p=fini_head; p; p=p->fini_next) {
|
|
|
-- if (!p->constructed) continue;
|
|
|
-- decode_vec(p->dynv, dyn, DYN_CNT);
|
|
|
-- if (dyn[0] & (1<<DT_FINI_ARRAY)) {
|
|
|
-- size_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t);
|
|
|
-- size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY])+n;
|
|
|
-- while (n--) ((void (*)(void))*--fn)();
|
|
|
-- }
|
|
|
--#ifndef NO_LEGACY_INITFINI
|
|
|
-- if ((dyn[0] & (1<<DT_FINI)) && dyn[DT_FINI])
|
|
|
-- fpaddr(p, dyn[DT_FINI])();
|
|
|
--#endif
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--static void do_init_fini(struct dso *p)
|
|
|
--{
|
|
|
-- size_t dyn[DYN_CNT];
|
|
|
-- int need_locking = libc.threads_minus_1;
|
|
|
-- /* Allow recursive calls that arise when a library calls
|
|
|
-- * dlopen from one of its constructors, but block any
|
|
|
-- * other threads until all ctors have finished. */
|
|
|
-- if (need_locking) pthread_mutex_lock(&init_fini_lock);
|
|
|
-- for (; p; p=p->prev) {
|
|
|
-- if (p->constructed) continue;
|
|
|
-- p->constructed = 1;
|
|
|
-- decode_vec(p->dynv, dyn, DYN_CNT);
|
|
|
-- if (dyn[0] & ((1<<DT_FINI) | (1<<DT_FINI_ARRAY))) {
|
|
|
-- p->fini_next = fini_head;
|
|
|
-- fini_head = p;
|
|
|
-- }
|
|
|
--#ifndef NO_LEGACY_INITFINI
|
|
|
-- if ((dyn[0] & (1<<DT_INIT)) && dyn[DT_INIT])
|
|
|
-- fpaddr(p, dyn[DT_INIT])();
|
|
|
--#endif
|
|
|
-- if (dyn[0] & (1<<DT_INIT_ARRAY)) {
|
|
|
-- size_t n = dyn[DT_INIT_ARRAYSZ]/sizeof(size_t);
|
|
|
-- size_t *fn = laddr(p, dyn[DT_INIT_ARRAY]);
|
|
|
-- while (n--) ((void (*)(void))*fn++)();
|
|
|
-- }
|
|
|
-- if (!need_locking && libc.threads_minus_1) {
|
|
|
-- need_locking = 1;
|
|
|
-- pthread_mutex_lock(&init_fini_lock);
|
|
|
-- }
|
|
|
-- }
|
|
|
-- if (need_locking) pthread_mutex_unlock(&init_fini_lock);
|
|
|
--}
|
|
|
--
|
|
|
--void __libc_start_init(void)
|
|
|
--{
|
|
|
-- do_init_fini(tail);
|
|
|
--}
|
|
|
--
|
|
|
--static void dl_debug_state(void)
|
|
|
--{
|
|
|
--}
|
|
|
--
|
|
|
--weak_alias(dl_debug_state, _dl_debug_state);
|
|
|
--
|
|
|
--void __reset_tls()
|
|
|
--{
|
|
|
-- pthread_t self = __pthread_self();
|
|
|
-- struct dso *p;
|
|
|
-- for (p=head; p; p=p->next) {
|
|
|
-- if (!p->tls_id || !self->dtv[p->tls_id]) continue;
|
|
|
-- memcpy(self->dtv[p->tls_id], p->tls_image, p->tls_len);
|
|
|
-- memset((char *)self->dtv[p->tls_id]+p->tls_len, 0,
|
|
|
-- p->tls_size - p->tls_len);
|
|
|
-- if (p->tls_id == (size_t)self->dtv[0]) break;
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--void *__copy_tls(unsigned char *mem)
|
|
|
--{
|
|
|
-- pthread_t td;
|
|
|
-- struct dso *p;
|
|
|
-- void **dtv;
|
|
|
--
|
|
|
--#ifdef TLS_ABOVE_TP
|
|
|
-- dtv = (void **)(mem + libc.tls_size) - (tls_cnt + 1);
|
|
|
--
|
|
|
-- mem += -((uintptr_t)mem + sizeof(struct pthread)) & (tls_align-1);
|
|
|
-- td = (pthread_t)mem;
|
|
|
-- mem += sizeof(struct pthread);
|
|
|
--
|
|
|
-- for (p=head; p; p=p->next) {
|
|
|
-- if (!p->tls_id) continue;
|
|
|
-- dtv[p->tls_id] = mem + p->tls_offset;
|
|
|
-- memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
|
|
|
-- }
|
|
|
--#else
|
|
|
-- dtv = (void **)mem;
|
|
|
--
|
|
|
-- mem += libc.tls_size - sizeof(struct pthread);
|
|
|
-- mem -= (uintptr_t)mem & (tls_align-1);
|
|
|
-- td = (pthread_t)mem;
|
|
|
--
|
|
|
-- for (p=head; p; p=p->next) {
|
|
|
-- if (!p->tls_id) continue;
|
|
|
-- dtv[p->tls_id] = mem - p->tls_offset;
|
|
|
-- memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
|
|
|
-- }
|
|
|
--#endif
|
|
|
-- dtv[0] = (void *)tls_cnt;
|
|
|
-- td->dtv = td->dtv_copy = dtv;
|
|
|
-- return td;
|
|
|
--}
|
|
|
--
|
|
|
--__attribute__((__visibility__("hidden")))
|
|
|
--void *__tls_get_new(size_t *v)
|
|
|
--{
|
|
|
-- pthread_t self = __pthread_self();
|
|
|
--
|
|
|
-- /* Block signals to make accessing new TLS async-signal-safe */
|
|
|
-- sigset_t set;
|
|
|
-- __block_all_sigs(&set);
|
|
|
-- if (v[0]<=(size_t)self->dtv[0]) {
|
|
|
-- __restore_sigs(&set);
|
|
|
-- return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
|
|
|
-- }
|
|
|
--
|
|
|
-- /* This is safe without any locks held because, if the caller
|
|
|
-- * is able to request the Nth entry of the DTV, the DSO list
|
|
|
-- * must be valid at least that far out and it was synchronized
|
|
|
-- * at program startup or by an already-completed call to dlopen. */
|
|
|
-- struct dso *p;
|
|
|
-- for (p=head; p->tls_id != v[0]; p=p->next);
|
|
|
--
|
|
|
-- /* Get new DTV space from new DSO if needed */
|
|
|
-- if (v[0] > (size_t)self->dtv[0]) {
|
|
|
-- void **newdtv = p->new_dtv +
|
|
|
-- (v[0]+1)*sizeof(void *)*a_fetch_add(&p->new_dtv_idx,1);
|
|
|
-- memcpy(newdtv, self->dtv,
|
|
|
-- ((size_t)self->dtv[0]+1) * sizeof(void *));
|
|
|
-- newdtv[0] = (void *)v[0];
|
|
|
-- self->dtv = self->dtv_copy = newdtv;
|
|
|
-- }
|
|
|
--
|
|
|
-- /* Get new TLS memory from all new DSOs up to the requested one */
|
|
|
-- unsigned char *mem;
|
|
|
-- for (p=head; ; p=p->next) {
|
|
|
-- if (!p->tls_id || self->dtv[p->tls_id]) continue;
|
|
|
-- mem = p->new_tls + (p->tls_size + p->tls_align)
|
|
|
-- * a_fetch_add(&p->new_tls_idx,1);
|
|
|
-- mem += ((uintptr_t)p->tls_image - (uintptr_t)mem)
|
|
|
-- & (p->tls_align-1);
|
|
|
-- self->dtv[p->tls_id] = mem;
|
|
|
-- memcpy(mem, p->tls_image, p->tls_len);
|
|
|
-- if (p->tls_id == v[0]) break;
|
|
|
-- }
|
|
|
-- __restore_sigs(&set);
|
|
|
-- return mem + v[1] + DTP_OFFSET;
|
|
|
--}
|
|
|
--
|
|
|
--static void update_tls_size()
|
|
|
--{
|
|
|
-- libc.tls_size = ALIGN(
|
|
|
-- (1+tls_cnt) * sizeof(void *) +
|
|
|
-- tls_offset +
|
|
|
-- sizeof(struct pthread) +
|
|
|
-- tls_align * 2,
|
|
|
-- tls_align);
|
|
|
--}
|
|
|
--
|
|
|
--/* Stage 1 of the dynamic linker is defined in dlstart.c. It calls the
|
|
|
-- * following stage 2 and stage 3 functions via primitive symbolic lookup
|
|
|
-- * since it does not have access to their addresses to begin with. */
|
|
|
--
|
|
|
--/* Stage 2 of the dynamic linker is called after relative relocations
|
|
|
-- * have been processed. It can make function calls to static functions
|
|
|
-- * and access string literals and static data, but cannot use extern
|
|
|
-- * symbols. Its job is to perform symbolic relocations on the dynamic
|
|
|
-- * linker itself, but some of the relocations performed may need to be
|
|
|
-- * replaced later due to copy relocations in the main program. */
|
|
|
--
|
|
|
--__attribute__((__visibility__("hidden")))
|
|
|
--void __dls2(unsigned char *base, size_t *sp)
|
|
|
--{
|
|
|
-- if (DL_FDPIC) {
|
|
|
-- void *p1 = (void *)sp[-2];
|
|
|
-- void *p2 = (void *)sp[-1];
|
|
|
-- if (!p1) {
|
|
|
-- size_t *auxv, aux[AUX_CNT];
|
|
|
-- for (auxv=sp+1+*sp+1; *auxv; auxv++); auxv++;
|
|
|
-- decode_vec(auxv, aux, AUX_CNT);
|
|
|
-- if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE];
|
|
|
-- else ldso.base = (void *)(aux[AT_PHDR] & -4096);
|
|
|
-- }
|
|
|
-- app_loadmap = p2 ? p1 : 0;
|
|
|
-- ldso.loadmap = p2 ? p2 : p1;
|
|
|
-- ldso.base = laddr(&ldso, 0);
|
|
|
-- } else {
|
|
|
-- ldso.base = base;
|
|
|
-- }
|
|
|
-- Ehdr *ehdr = (void *)ldso.base;
|
|
|
-- ldso.name = ldso.shortname = "libc.so";
|
|
|
-- ldso.global = 1;
|
|
|
-- ldso.phnum = ehdr->e_phnum;
|
|
|
-- ldso.phdr = laddr(&ldso, ehdr->e_phoff);
|
|
|
-- ldso.phentsize = ehdr->e_phentsize;
|
|
|
-- kernel_mapped_dso(&ldso);
|
|
|
-- decode_dyn(&ldso);
|
|
|
--
|
|
|
-- if (DL_FDPIC) makefuncdescs(&ldso);
|
|
|
--
|
|
|
-- /* Prepare storage for to save clobbered REL addends so they
|
|
|
-- * can be reused in stage 3. There should be very few. If
|
|
|
-- * something goes wrong and there are a huge number, abort
|
|
|
-- * instead of risking stack overflow. */
|
|
|
-- size_t dyn[DYN_CNT];
|
|
|
-- decode_vec(ldso.dynv, dyn, DYN_CNT);
|
|
|
-- size_t *rel = laddr(&ldso, dyn[DT_REL]);
|
|
|
-- size_t rel_size = dyn[DT_RELSZ];
|
|
|
-- size_t symbolic_rel_cnt = 0;
|
|
|
-- apply_addends_to = rel;
|
|
|
-- for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t))
|
|
|
-- if (!IS_RELATIVE(rel[1], ldso.syms)) symbolic_rel_cnt++;
|
|
|
-- if (symbolic_rel_cnt >= ADDEND_LIMIT) a_crash();
|
|
|
-- size_t addends[symbolic_rel_cnt+1];
|
|
|
-- saved_addends = addends;
|
|
|
--
|
|
|
-- head = &ldso;
|
|
|
-- reloc_all(&ldso);
|
|
|
--
|
|
|
-- ldso.relocated = 0;
|
|
|
--
|
|
|
-- /* Call dynamic linker stage-3, __dls3, looking it up
|
|
|
-- * symbolically as a barrier against moving the address
|
|
|
-- * load across the above relocation processing. */
|
|
|
-- struct symdef dls3_def = find_sym(&ldso, "__dls3", 0);
|
|
|
-- if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp);
|
|
|
-- else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp);
|
|
|
--}
|
|
|
--
|
|
|
--/* Stage 3 of the dynamic linker is called with the dynamic linker/libc
|
|
|
-- * fully functional. Its job is to load (if not already loaded) and
|
|
|
-- * process dependencies and relocations for the main application and
|
|
|
-- * transfer control to its entry point. */
|
|
|
--
|
|
|
--_Noreturn void __dls3(size_t *sp)
|
|
|
--{
|
|
|
-- static struct dso app, vdso;
|
|
|
-- size_t aux[AUX_CNT], *auxv;
|
|
|
-- size_t i;
|
|
|
-- char *env_preload=0;
|
|
|
-- size_t vdso_base;
|
|
|
-- int argc = *sp;
|
|
|
-- char **argv = (void *)(sp+1);
|
|
|
-- char **argv_orig = argv;
|
|
|
-- char **envp = argv+argc+1;
|
|
|
--
|
|
|
-- /* Find aux vector just past environ[] and use it to initialize
|
|
|
-- * global data that may be needed before we can make syscalls. */
|
|
|
-- __environ = envp;
|
|
|
-- for (i=argc+1; argv[i]; i++);
|
|
|
-- libc.auxv = auxv = (void *)(argv+i+1);
|
|
|
-- decode_vec(auxv, aux, AUX_CNT);
|
|
|
-- __hwcap = aux[AT_HWCAP];
|
|
|
-- libc.page_size = aux[AT_PAGESZ];
|
|
|
-- libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
|
|
|
-- || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]);
|
|
|
--
|
|
|
-- /* Setup early thread pointer in builtin_tls for ldso/libc itself to
|
|
|
-- * use during dynamic linking. If possible it will also serve as the
|
|
|
-- * thread pointer at runtime. */
|
|
|
-- libc.tls_size = sizeof builtin_tls;
|
|
|
-- if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {
|
|
|
-- a_crash();
|
|
|
-- }
|
|
|
--
|
|
|
-- /* Only trust user/env if kernel says we're not suid/sgid */
|
|
|
-- if (!libc.secure) {
|
|
|
-- env_path = getenv("LD_LIBRARY_PATH");
|
|
|
-- env_preload = getenv("LD_PRELOAD");
|
|
|
-- }
|
|
|
--
|
|
|
-- /* If the main program was already loaded by the kernel,
|
|
|
-- * AT_PHDR will point to some location other than the dynamic
|
|
|
-- * linker's program headers. */
|
|
|
-- if (aux[AT_PHDR] != (size_t)ldso.phdr) {
|
|
|
-- size_t interp_off = 0;
|
|
|
-- size_t tls_image = 0;
|
|
|
-- /* Find load address of the main program, via AT_PHDR vs PT_PHDR. */
|
|
|
-- Phdr *phdr = app.phdr = (void *)aux[AT_PHDR];
|
|
|
-- app.phnum = aux[AT_PHNUM];
|
|
|
-- app.phentsize = aux[AT_PHENT];
|
|
|
-- for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) {
|
|
|
-- if (phdr->p_type == PT_PHDR)
|
|
|
-- app.base = (void *)(aux[AT_PHDR] - phdr->p_vaddr);
|
|
|
-- else if (phdr->p_type == PT_INTERP)
|
|
|
-- interp_off = (size_t)phdr->p_vaddr;
|
|
|
-- else if (phdr->p_type == PT_TLS) {
|
|
|
-- tls_image = phdr->p_vaddr;
|
|
|
-- app.tls_len = phdr->p_filesz;
|
|
|
-- app.tls_size = phdr->p_memsz;
|
|
|
-- app.tls_align = phdr->p_align;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- if (DL_FDPIC) app.loadmap = app_loadmap;
|
|
|
-- if (app.tls_size) app.tls_image = laddr(&app, tls_image);
|
|
|
-- if (interp_off) ldso.name = laddr(&app, interp_off);
|
|
|
-- if ((aux[0] & (1UL<<AT_EXECFN))
|
|
|
-- && strncmp((char *)aux[AT_EXECFN], "/proc/", 6))
|
|
|
-- app.name = (char *)aux[AT_EXECFN];
|
|
|
-- else
|
|
|
-- app.name = argv[0];
|
|
|
-- kernel_mapped_dso(&app);
|
|
|
-- } else {
|
|
|
-- int fd;
|
|
|
-- char *ldname = argv[0];
|
|
|
-- size_t l = strlen(ldname);
|
|
|
-- if (l >= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1;
|
|
|
-- argv++;
|
|
|
-- while (argv[0] && argv[0][0]=='-' && argv[0][1]=='-') {
|
|
|
-- char *opt = argv[0]+2;
|
|
|
-- *argv++ = (void *)-1;
|
|
|
-- if (!*opt) {
|
|
|
-- break;
|
|
|
-- } else if (!memcmp(opt, "list", 5)) {
|
|
|
-- ldd_mode = 1;
|
|
|
-- } else if (!memcmp(opt, "library-path", 12)) {
|
|
|
-- if (opt[12]=='=') env_path = opt+13;
|
|
|
-- else if (opt[12]) *argv = 0;
|
|
|
-- else if (*argv) env_path = *argv++;
|
|
|
-- } else if (!memcmp(opt, "preload", 7)) {
|
|
|
-- if (opt[7]=='=') env_preload = opt+8;
|
|
|
-- else if (opt[7]) *argv = 0;
|
|
|
-- else if (*argv) env_preload = *argv++;
|
|
|
-- } else {
|
|
|
-- argv[0] = 0;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- argv[-1] = (void *)(argc - (argv-argv_orig));
|
|
|
-- if (!argv[0]) {
|
|
|
-- dprintf(2, "musl libc\n"
|
|
|
-- "Version %s\n"
|
|
|
-- "Dynamic Program Loader\n"
|
|
|
-- "Usage: %s [options] [--] pathname%s\n",
|
|
|
-- __libc_get_version(), ldname,
|
|
|
-- ldd_mode ? "" : " [args]");
|
|
|
-- _exit(1);
|
|
|
-- }
|
|
|
-- fd = open(argv[0], O_RDONLY);
|
|
|
-- if (fd < 0) {
|
|
|
-- dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno));
|
|
|
-- _exit(1);
|
|
|
-- }
|
|
|
-- runtime = 1;
|
|
|
-- Ehdr *ehdr = (void *)map_library(fd, &app);
|
|
|
-- if (!ehdr) {
|
|
|
-- dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]);
|
|
|
-- _exit(1);
|
|
|
-- }
|
|
|
-- runtime = 0;
|
|
|
-- close(fd);
|
|
|
-- ldso.name = ldname;
|
|
|
-- app.name = argv[0];
|
|
|
-- aux[AT_ENTRY] = (size_t)laddr(&app, ehdr->e_entry);
|
|
|
-- /* Find the name that would have been used for the dynamic
|
|
|
-- * linker had ldd not taken its place. */
|
|
|
-- if (ldd_mode) {
|
|
|
-- for (i=0; i<app.phnum; i++) {
|
|
|
-- if (app.phdr[i].p_type == PT_INTERP)
|
|
|
-- ldso.name = laddr(&app, app.phdr[i].p_vaddr);
|
|
|
-- }
|
|
|
-- dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base);
|
|
|
-- }
|
|
|
-- }
|
|
|
-- if (app.tls_size) {
|
|
|
-- app.tls_id = tls_cnt = 1;
|
|
|
--#ifdef TLS_ABOVE_TP
|
|
|
-- app.tls_offset = 0;
|
|
|
-- tls_offset = app.tls_size
|
|
|
-- + ( -((uintptr_t)app.tls_image + app.tls_size)
|
|
|
-- & (app.tls_align-1) );
|
|
|
--#else
|
|
|
-- tls_offset = app.tls_offset = app.tls_size
|
|
|
-- + ( -((uintptr_t)app.tls_image + app.tls_size)
|
|
|
-- & (app.tls_align-1) );
|
|
|
--#endif
|
|
|
-- tls_align = MAXP2(tls_align, app.tls_align);
|
|
|
-- }
|
|
|
-- app.global = 1;
|
|
|
-- decode_dyn(&app);
|
|
|
-- if (DL_FDPIC) {
|
|
|
-- makefuncdescs(&app);
|
|
|
-- if (!app.loadmap) {
|
|
|
-- app.loadmap = (void *)&app_dummy_loadmap;
|
|
|
-- app.loadmap->nsegs = 1;
|
|
|
-- app.loadmap->segs[0].addr = (size_t)app.map;
|
|
|
-- app.loadmap->segs[0].p_vaddr = (size_t)app.map
|
|
|
-- - (size_t)app.base;
|
|
|
-- app.loadmap->segs[0].p_memsz = app.map_len;
|
|
|
-- }
|
|
|
-- argv[-3] = (void *)app.loadmap;
|
|
|
-- }
|
|
|
--
|
|
|
-- /* Attach to vdso, if provided by the kernel */
|
|
|
-- if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR)) {
|
|
|
-- Ehdr *ehdr = (void *)vdso_base;
|
|
|
-- Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff);
|
|
|
-- vdso.phnum = ehdr->e_phnum;
|
|
|
-- vdso.phentsize = ehdr->e_phentsize;
|
|
|
-- for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
|
|
|
-- if (phdr->p_type == PT_DYNAMIC)
|
|
|
-- vdso.dynv = (void *)(vdso_base + phdr->p_offset);
|
|
|
-- if (phdr->p_type == PT_LOAD)
|
|
|
-- vdso.base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);
|
|
|
-- }
|
|
|
-- vdso.name = "";
|
|
|
-- vdso.shortname = "linux-gate.so.1";
|
|
|
-- vdso.global = 1;
|
|
|
-- vdso.relocated = 1;
|
|
|
-- decode_dyn(&vdso);
|
|
|
-- vdso.prev = &ldso;
|
|
|
-- ldso.next = &vdso;
|
|
|
-- }
|
|
|
--
|
|
|
-- /* Initial dso chain consists only of the app. */
|
|
|
-- head = tail = &app;
|
|
|
--
|
|
|
-- /* Donate unused parts of app and library mapping to malloc */
|
|
|
-- reclaim_gaps(&app);
|
|
|
-- reclaim_gaps(&ldso);
|
|
|
--
|
|
|
-- /* Load preload/needed libraries, add their symbols to the global
|
|
|
-- * namespace, and perform all remaining relocations. */
|
|
|
-- if (env_preload) load_preload(env_preload);
|
|
|
-- load_deps(&app);
|
|
|
-- make_global(&app);
|
|
|
--
|
|
|
--#ifndef DYNAMIC_IS_RO
|
|
|
-- for (i=0; app.dynv[i]; i+=2)
|
|
|
-- if (app.dynv[i]==DT_DEBUG)
|
|
|
-- app.dynv[i+1] = (size_t)&debug;
|
|
|
--#endif
|
|
|
--
|
|
|
-- /* The main program must be relocated LAST since it may contin
|
|
|
-- * copy relocations which depend on libraries' relocations. */
|
|
|
-- reloc_all(app.next);
|
|
|
-- reloc_all(&app);
|
|
|
--
|
|
|
-- update_tls_size();
|
|
|
-- if (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) {
|
|
|
-- void *initial_tls = calloc(libc.tls_size, 1);
|
|
|
-- if (!initial_tls) {
|
|
|
-- dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n",
|
|
|
-- argv[0], libc.tls_size);
|
|
|
-- _exit(127);
|
|
|
-- }
|
|
|
-- if (__init_tp(__copy_tls(initial_tls)) < 0) {
|
|
|
-- a_crash();
|
|
|
-- }
|
|
|
-- } else {
|
|
|
-- size_t tmp_tls_size = libc.tls_size;
|
|
|
-- pthread_t self = __pthread_self();
|
|
|
-- /* Temporarily set the tls size to the full size of
|
|
|
-- * builtin_tls so that __copy_tls will use the same layout
|
|
|
-- * as it did for before. Then check, just to be safe. */
|
|
|
-- libc.tls_size = sizeof builtin_tls;
|
|
|
-- if (__copy_tls((void*)builtin_tls) != self) a_crash();
|
|
|
-- libc.tls_size = tmp_tls_size;
|
|
|
-- }
|
|
|
-- static_tls_cnt = tls_cnt;
|
|
|
--
|
|
|
-- if (ldso_fail) _exit(127);
|
|
|
-- if (ldd_mode) _exit(0);
|
|
|
--
|
|
|
-- /* Switch to runtime mode: any further failures in the dynamic
|
|
|
-- * linker are a reportable failure rather than a fatal startup
|
|
|
-- * error. */
|
|
|
-- runtime = 1;
|
|
|
--
|
|
|
-- debug.ver = 1;
|
|
|
-- debug.bp = dl_debug_state;
|
|
|
-- debug.head = head;
|
|
|
-- debug.base = ldso.base;
|
|
|
-- debug.state = 0;
|
|
|
-- _dl_debug_state();
|
|
|
--
|
|
|
-- __init_libc(envp, argv[0]);
|
|
|
-- atexit(do_fini);
|
|
|
-- errno = 0;
|
|
|
--
|
|
|
-- CRTJMP((void *)aux[AT_ENTRY], argv-1);
|
|
|
-- for(;;);
|
|
|
--}
|
|
|
--
|
|
|
--void *dlopen(const char *file, int mode)
|
|
|
--{
|
|
|
-- struct dso *volatile p, *orig_tail, *next;
|
|
|
-- size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;
|
|
|
-- size_t i;
|
|
|
-- int cs;
|
|
|
-- jmp_buf jb;
|
|
|
--
|
|
|
-- if (!file) return head;
|
|
|
--
|
|
|
-- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
|
|
|
-- pthread_rwlock_wrlock(&lock);
|
|
|
-- __inhibit_ptc();
|
|
|
--
|
|
|
-- p = 0;
|
|
|
-- orig_tls_cnt = tls_cnt;
|
|
|
-- orig_tls_offset = tls_offset;
|
|
|
-- orig_tls_align = tls_align;
|
|
|
-- orig_tail = tail;
|
|
|
-- noload = mode & RTLD_NOLOAD;
|
|
|
--
|
|
|
-- rtld_fail = &jb;
|
|
|
-- if (setjmp(*rtld_fail)) {
|
|
|
-- /* Clean up anything new that was (partially) loaded */
|
|
|
-- if (p && p->deps) for (i=0; p->deps[i]; i++)
|
|
|
-- if (p->deps[i]->global < 0)
|
|
|
-- p->deps[i]->global = 0;
|
|
|
-- for (p=orig_tail->next; p; p=next) {
|
|
|
-- next = p->next;
|
|
|
-- while (p->td_index) {
|
|
|
-- void *tmp = p->td_index->next;
|
|
|
-- free(p->td_index);
|
|
|
-- p->td_index = tmp;
|
|
|
-- }
|
|
|
-- free(p->funcdescs);
|
|
|
-- if (p->rpath != p->rpath_orig)
|
|
|
-- free(p->rpath);
|
|
|
-- free(p->deps);
|
|
|
-- unmap_library(p);
|
|
|
-- free(p);
|
|
|
-- }
|
|
|
-- tls_cnt = orig_tls_cnt;
|
|
|
-- tls_offset = orig_tls_offset;
|
|
|
-- tls_align = orig_tls_align;
|
|
|
-- tail = orig_tail;
|
|
|
-- tail->next = 0;
|
|
|
-- p = 0;
|
|
|
-- goto end;
|
|
|
-- } else p = load_library(file, head);
|
|
|
--
|
|
|
-- if (!p) {
|
|
|
-- error(noload ?
|
|
|
-- "Library %s is not already loaded" :
|
|
|
-- "Error loading shared library %s: %m",
|
|
|
-- file);
|
|
|
-- goto end;
|
|
|
-- }
|
|
|
--
|
|
|
-- /* First load handling */
|
|
|
-- if (!p->deps) {
|
|
|
-- load_deps(p);
|
|
|
-- if (p->deps) for (i=0; p->deps[i]; i++)
|
|
|
-- if (!p->deps[i]->global)
|
|
|
-- p->deps[i]->global = -1;
|
|
|
-- if (!p->global) p->global = -1;
|
|
|
-- reloc_all(p);
|
|
|
-- if (p->deps) for (i=0; p->deps[i]; i++)
|
|
|
-- if (p->deps[i]->global < 0)
|
|
|
-- p->deps[i]->global = 0;
|
|
|
-- if (p->global < 0) p->global = 0;
|
|
|
-- }
|
|
|
--
|
|
|
-- if (mode & RTLD_GLOBAL) {
|
|
|
-- if (p->deps) for (i=0; p->deps[i]; i++)
|
|
|
-- p->deps[i]->global = 1;
|
|
|
-- p->global = 1;
|
|
|
-- }
|
|
|
--
|
|
|
-- update_tls_size();
|
|
|
-- _dl_debug_state();
|
|
|
-- orig_tail = tail;
|
|
|
--end:
|
|
|
-- __release_ptc();
|
|
|
-- if (p) gencnt++;
|
|
|
-- pthread_rwlock_unlock(&lock);
|
|
|
-- if (p) do_init_fini(orig_tail);
|
|
|
-- pthread_setcancelstate(cs, 0);
|
|
|
-- return p;
|
|
|
--}
|
|
|
--
|
|
|
--static int invalid_dso_handle(void *h)
|
|
|
--{
|
|
|
-- struct dso *p;
|
|
|
-- for (p=head; p; p=p->next) if (h==p) return 0;
|
|
|
-- error("Invalid library handle %p", (void *)h);
|
|
|
-- return 1;
|
|
|
--}
|
|
|
--
|
|
|
--static void *addr2dso(size_t a)
|
|
|
--{
|
|
|
-- struct dso *p;
|
|
|
-- size_t i;
|
|
|
-- if (DL_FDPIC) for (p=head; p; p=p->next) {
|
|
|
-- i = count_syms(p);
|
|
|
-- if (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs))
|
|
|
-- return p;
|
|
|
-- }
|
|
|
-- for (p=head; p; p=p->next) {
|
|
|
-- if (DL_FDPIC && p->loadmap) {
|
|
|
-- for (i=0; i<p->loadmap->nsegs; i++) {
|
|
|
-- if (a-p->loadmap->segs[i].p_vaddr
|
|
|
-- < p->loadmap->segs[i].p_memsz)
|
|
|
-- return p;
|
|
|
-- }
|
|
|
-- } else {
|
|
|
-- if (a-(size_t)p->map < p->map_len)
|
|
|
-- return p;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- return 0;
|
|
|
--}
|
|
|
--
|
|
|
--void *__tls_get_addr(size_t *);
|
|
|
--
|
|
|
--static void *do_dlsym(struct dso *p, const char *s, void *ra)
|
|
|
--{
|
|
|
-- size_t i;
|
|
|
-- uint32_t h = 0, gh = 0, *ght;
|
|
|
-- Sym *sym;
|
|
|
-- if (p == head || p == RTLD_DEFAULT || p == RTLD_NEXT) {
|
|
|
-- if (p == RTLD_DEFAULT) {
|
|
|
-- p = head;
|
|
|
-- } else if (p == RTLD_NEXT) {
|
|
|
-- p = addr2dso((size_t)ra);
|
|
|
-- if (!p) p=head;
|
|
|
-- p = p->next;
|
|
|
-- }
|
|
|
-- struct symdef def = find_sym(p, s, 0);
|
|
|
-- if (!def.sym) goto failed;
|
|
|
-- if ((def.sym->st_info&0xf) == STT_TLS)
|
|
|
-- return __tls_get_addr((size_t []){def.dso->tls_id, def.sym->st_value});
|
|
|
-- if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC)
|
|
|
-- return def.dso->funcdescs + (def.sym - def.dso->syms);
|
|
|
-- return laddr(def.dso, def.sym->st_value);
|
|
|
-- }
|
|
|
-- if (invalid_dso_handle(p))
|
|
|
-- return 0;
|
|
|
-- if ((ght = p->ghashtab)) {
|
|
|
-- gh = gnu_hash(s);
|
|
|
-- sym = gnu_lookup(gh, ght, p, s);
|
|
|
-- } else {
|
|
|
-- h = sysv_hash(s);
|
|
|
-- sym = sysv_lookup(s, h, p);
|
|
|
-- }
|
|
|
-- if (sym && (sym->st_info&0xf) == STT_TLS)
|
|
|
-- return __tls_get_addr((size_t []){p->tls_id, sym->st_value});
|
|
|
-- if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC)
|
|
|
-- return p->funcdescs + (sym - p->syms);
|
|
|
-- if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
|
|
|
-- return laddr(p, sym->st_value);
|
|
|
-- if (p->deps) for (i=0; p->deps[i]; i++) {
|
|
|
-- if ((ght = p->deps[i]->ghashtab)) {
|
|
|
-- if (!gh) gh = gnu_hash(s);
|
|
|
-- sym = gnu_lookup(gh, ght, p->deps[i], s);
|
|
|
-- } else {
|
|
|
-- if (!h) h = sysv_hash(s);
|
|
|
-- sym = sysv_lookup(s, h, p->deps[i]);
|
|
|
-- }
|
|
|
-- if (sym && (sym->st_info&0xf) == STT_TLS)
|
|
|
-- return __tls_get_addr((size_t []){p->deps[i]->tls_id, sym->st_value});
|
|
|
-- if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC)
|
|
|
-- return p->deps[i]->funcdescs + (sym - p->deps[i]->syms);
|
|
|
-- if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
|
|
|
-- return laddr(p->deps[i], sym->st_value);
|
|
|
-- }
|
|
|
--failed:
|
|
|
-- error("Symbol not found: %s", s);
|
|
|
-- return 0;
|
|
|
--}
|
|
|
--
|
|
|
--int __dladdr(const void *addr, Dl_info *info)
|
|
|
--{
|
|
|
-- struct dso *p;
|
|
|
-- Sym *sym, *bestsym;
|
|
|
-- uint32_t nsym;
|
|
|
-- char *strings;
|
|
|
-- void *best = 0;
|
|
|
--
|
|
|
-- pthread_rwlock_rdlock(&lock);
|
|
|
-- p = addr2dso((size_t)addr);
|
|
|
-- pthread_rwlock_unlock(&lock);
|
|
|
--
|
|
|
-- if (!p) return 0;
|
|
|
--
|
|
|
-- sym = p->syms;
|
|
|
-- strings = p->strings;
|
|
|
-- nsym = count_syms(p);
|
|
|
--
|
|
|
-- if (DL_FDPIC) {
|
|
|
-- size_t idx = ((size_t)addr-(size_t)p->funcdescs)
|
|
|
-- / sizeof(*p->funcdescs);
|
|
|
-- if (idx < nsym && (sym[idx].st_info&0xf) == STT_FUNC) {
|
|
|
-- best = p->funcdescs + idx;
|
|
|
-- bestsym = sym + idx;
|
|
|
-- }
|
|
|
-- }
|
|
|
--
|
|
|
-- if (!best) for (; nsym; nsym--, sym++) {
|
|
|
-- if (sym->st_value
|
|
|
-- && (1<<(sym->st_info&0xf) & OK_TYPES)
|
|
|
-- && (1<<(sym->st_info>>4) & OK_BINDS)) {
|
|
|
-- void *symaddr = laddr(p, sym->st_value);
|
|
|
-- if (symaddr > addr || symaddr < best)
|
|
|
-- continue;
|
|
|
-- best = symaddr;
|
|
|
-- bestsym = sym;
|
|
|
-- if (addr == symaddr)
|
|
|
-- break;
|
|
|
-- }
|
|
|
-- }
|
|
|
--
|
|
|
-- if (!best) return 0;
|
|
|
--
|
|
|
-- if (DL_FDPIC && (bestsym->st_info&0xf) == STT_FUNC)
|
|
|
-- best = p->funcdescs + (bestsym - p->syms);
|
|
|
--
|
|
|
-- info->dli_fname = p->name;
|
|
|
-- info->dli_fbase = p->base;
|
|
|
-- info->dli_sname = strings + bestsym->st_name;
|
|
|
-- info->dli_saddr = best;
|
|
|
--
|
|
|
-- return 1;
|
|
|
--}
|
|
|
--
|
|
|
--__attribute__((__visibility__("hidden")))
|
|
|
--void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
|
|
|
--{
|
|
|
-- void *res;
|
|
|
-- pthread_rwlock_rdlock(&lock);
|
|
|
-- res = do_dlsym(p, s, ra);
|
|
|
-- pthread_rwlock_unlock(&lock);
|
|
|
-- return res;
|
|
|
--}
|
|
|
--
|
|
|
--int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
|
|
|
--{
|
|
|
-- struct dso *current;
|
|
|
-- struct dl_phdr_info info;
|
|
|
-- int ret = 0;
|
|
|
-- for(current = head; current;) {
|
|
|
-- info.dlpi_addr = (uintptr_t)current->base;
|
|
|
-- info.dlpi_name = current->name;
|
|
|
-- info.dlpi_phdr = current->phdr;
|
|
|
-- info.dlpi_phnum = current->phnum;
|
|
|
-- info.dlpi_adds = gencnt;
|
|
|
-- info.dlpi_subs = 0;
|
|
|
-- info.dlpi_tls_modid = current->tls_id;
|
|
|
-- info.dlpi_tls_data = current->tls_image;
|
|
|
--
|
|
|
-- ret = (callback)(&info, sizeof (info), data);
|
|
|
--
|
|
|
-- if (ret != 0) break;
|
|
|
--
|
|
|
-- pthread_rwlock_rdlock(&lock);
|
|
|
-- current = current->next;
|
|
|
-- pthread_rwlock_unlock(&lock);
|
|
|
-- }
|
|
|
-- return ret;
|
|
|
--}
|
|
|
--#else
|
|
|
--static int invalid_dso_handle(void *h)
|
|
|
--{
|
|
|
-- error("Invalid library handle %p", (void *)h);
|
|
|
-- return 1;
|
|
|
--}
|
|
|
--void *dlopen(const char *file, int mode)
|
|
|
--{
|
|
|
-- error("Dynamic loading not supported");
|
|
|
-- return 0;
|
|
|
--}
|
|
|
--void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
|
|
|
--{
|
|
|
-- error("Symbol not found: %s", s);
|
|
|
-- return 0;
|
|
|
--}
|
|
|
--int __dladdr (const void *addr, Dl_info *info)
|
|
|
--{
|
|
|
-- return 0;
|
|
|
--}
|
|
|
--#endif
|
|
|
--
|
|
|
--int __dlinfo(void *dso, int req, void *res)
|
|
|
--{
|
|
|
-- if (invalid_dso_handle(dso)) return -1;
|
|
|
-- if (req != RTLD_DI_LINKMAP) {
|
|
|
-- error("Unsupported request %d", req);
|
|
|
-- return -1;
|
|
|
-- }
|
|
|
-- *(struct link_map **)res = dso;
|
|
|
-- return 0;
|
|
|
--}
|
|
|
--
|
|
|
--char *dlerror()
|
|
|
--{
|
|
|
-- pthread_t self = __pthread_self();
|
|
|
-- if (!self->dlerror_flag) return 0;
|
|
|
-- self->dlerror_flag = 0;
|
|
|
-- char *s = self->dlerror_buf;
|
|
|
-- if (s == (void *)-1)
|
|
|
-- return "Dynamic linker failed to allocate memory for error message";
|
|
|
-- else
|
|
|
-- return s;
|
|
|
--}
|
|
|
--
|
|
|
--int dlclose(void *p)
|
|
|
--{
|
|
|
-- return invalid_dso_handle(p);
|
|
|
--}
|
|
|
--
|
|
|
--void __dl_thread_cleanup(void)
|
|
|
--{
|
|
|
-- pthread_t self = __pthread_self();
|
|
|
-- if (self->dlerror_buf != (void *)-1)
|
|
|
-- free(self->dlerror_buf);
|
|
|
--}
|
|
|
--
|
|
|
--static void error(const char *fmt, ...)
|
|
|
--{
|
|
|
-- va_list ap;
|
|
|
-- va_start(ap, fmt);
|
|
|
--#ifdef SHARED
|
|
|
-- if (!runtime) {
|
|
|
-- vdprintf(2, fmt, ap);
|
|
|
-- dprintf(2, "\n");
|
|
|
-- ldso_fail = 1;
|
|
|
-- va_end(ap);
|
|
|
-- return;
|
|
|
-- }
|
|
|
--#endif
|
|
|
-- pthread_t self = __pthread_self();
|
|
|
-- if (self->dlerror_buf != (void *)-1)
|
|
|
-- free(self->dlerror_buf);
|
|
|
-- size_t len = vsnprintf(0, 0, fmt, ap);
|
|
|
-- va_end(ap);
|
|
|
-- char *buf = malloc(len+1);
|
|
|
-- if (buf) {
|
|
|
-- va_start(ap, fmt);
|
|
|
-- vsnprintf(buf, len+1, fmt, ap);
|
|
|
-- va_end(ap);
|
|
|
-- } else {
|
|
|
-- buf = (void *)-1;
|
|
|
-- }
|
|
|
-- self->dlerror_buf = buf;
|
|
|
-- self->dlerror_flag = 1;
|
|
|
--}
|
|
|
---- a/src/ldso/tlsdesc.c
|
|
|
-+++ b/src/ldso/tlsdesc.c
|
|
|
-@@ -1,5 +1,3 @@
|
|
|
--#ifdef SHARED
|
|
|
--
|
|
|
- #include <stddef.h>
|
|
|
- #include "libc.h"
|
|
|
-
|
|
|
-@@ -12,5 +10,3 @@ ptrdiff_t __tlsdesc_static()
|
|
|
- }
|
|
|
-
|
|
|
- weak_alias(__tlsdesc_static, __tlsdesc_dynamic);
|
|
|
--
|
|
|
--#endif
|
|
|
---- a/src/legacy/utmpx.c
|
|
|
-+++ b/src/legacy/utmpx.c
|
|
|
-@@ -1,5 +1,6 @@
|
|
|
- #include <utmpx.h>
|
|
|
- #include <stddef.h>
|
|
|
-+#include <errno.h>
|
|
|
- #include "libc.h"
|
|
|
-
|
|
|
- void endutxent(void)
|
|
|
-@@ -34,6 +35,12 @@ void updwtmpx(const char *f, const struc
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
-+int __utmpxname(const char *f)
|
|
|
-+{
|
|
|
-+ errno = ENOTSUP;
|
|
|
-+ return -1;
|
|
|
-+}
|
|
|
-+
|
|
|
- weak_alias(endutxent, endutent);
|
|
|
- weak_alias(setutxent, setutent);
|
|
|
- weak_alias(getutxent, getutent);
|
|
|
-@@ -41,3 +48,5 @@ weak_alias(getutxid, getutid);
|
|
|
- weak_alias(getutxline, getutline);
|
|
|
- weak_alias(pututxline, pututline);
|
|
|
- weak_alias(updwtmpx, updwtmp);
|
|
|
-+weak_alias(__utmpxname, utmpname);
|
|
|
-+weak_alias(__utmpxname, utmpxname);
|
|
|
---- /dev/null
|
|
|
-+++ b/src/linux/x32/sysinfo.c
|
|
|
-@@ -0,0 +1,50 @@
|
|
|
-+#include <sys/sysinfo.h>
|
|
|
-+#include "syscall.h"
|
|
|
-+#include "libc.h"
|
|
|
-+
|
|
|
-+#define klong long long
|
|
|
-+#define kulong unsigned long long
|
|
|
-+
|
|
|
-+struct kernel_sysinfo {
|
|
|
-+ klong uptime;
|
|
|
-+ kulong loads[3];
|
|
|
-+ kulong totalram;
|
|
|
-+ kulong freeram;
|
|
|
-+ kulong sharedram;
|
|
|
-+ kulong bufferram;
|
|
|
-+ kulong totalswap;
|
|
|
-+ kulong freeswap;
|
|
|
-+ short procs;
|
|
|
-+ short pad;
|
|
|
-+ kulong totalhigh;
|
|
|
-+ kulong freehigh;
|
|
|
-+ unsigned mem_unit;
|
|
|
-+};
|
|
|
-+
|
|
|
-+int __lsysinfo(struct sysinfo *info)
|
|
|
-+{
|
|
|
-+ struct kernel_sysinfo tmp;
|
|
|
-+ int ret = syscall(SYS_sysinfo, &tmp);
|
|
|
-+ if(ret == -1) return ret;
|
|
|
-+ info->uptime = tmp.uptime;
|
|
|
-+ info->loads[0] = tmp.loads[0];
|
|
|
-+ info->loads[1] = tmp.loads[1];
|
|
|
-+ info->loads[2] = tmp.loads[2];
|
|
|
-+ kulong shifts;
|
|
|
-+ kulong max = tmp.totalram | tmp.totalswap;
|
|
|
-+ __asm__("bsr %1,%0" : "=r"(shifts) : "r"(max));
|
|
|
-+ shifts = shifts >= 32 ? shifts - 31 : 0;
|
|
|
-+ info->totalram = tmp.totalram >> shifts;
|
|
|
-+ info->freeram = tmp.freeram >> shifts;
|
|
|
-+ info->sharedram = tmp.sharedram >> shifts;
|
|
|
-+ info->bufferram = tmp.bufferram >> shifts;
|
|
|
-+ info->totalswap = tmp.totalswap >> shifts;
|
|
|
-+ info->freeswap = tmp.freeswap >> shifts;
|
|
|
-+ info->procs = tmp.procs ;
|
|
|
-+ info->totalhigh = tmp.totalhigh >> shifts;
|
|
|
-+ info->freehigh = tmp.freehigh >> shifts;
|
|
|
-+ info->mem_unit = (tmp.mem_unit ? tmp.mem_unit : 1) << shifts;
|
|
|
-+ return ret;
|
|
|
-+}
|
|
|
-+
|
|
|
-+weak_alias(__lsysinfo, sysinfo);
|
|
|
---- a/src/linux/x32/sysinfo.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--# see arch/x32/src/sysinfo.c
|
|
|
---- a/src/locale/langinfo.c
|
|
|
-+++ b/src/locale/langinfo.c
|
|
|
-@@ -37,23 +37,23 @@ char *__nl_langinfo_l(nl_item item, loca
|
|
|
-
|
|
|
- switch (cat) {
|
|
|
- case LC_NUMERIC:
|
|
|
-- if (idx > 1) return NULL;
|
|
|
-+ if (idx > 1) return "";
|
|
|
- str = c_numeric;
|
|
|
- break;
|
|
|
- case LC_TIME:
|
|
|
-- if (idx > 0x31) return NULL;
|
|
|
-+ if (idx > 0x31) return "";
|
|
|
- str = c_time;
|
|
|
- break;
|
|
|
- case LC_MONETARY:
|
|
|
-- if (idx > 0) return NULL;
|
|
|
-+ if (idx > 0) return "";
|
|
|
- str = "";
|
|
|
- break;
|
|
|
- case LC_MESSAGES:
|
|
|
-- if (idx > 3) return NULL;
|
|
|
-+ if (idx > 3) return "";
|
|
|
- str = c_messages;
|
|
|
- break;
|
|
|
- default:
|
|
|
-- return NULL;
|
|
|
-+ return "";
|
|
|
- }
|
|
|
-
|
|
|
- for (; idx; idx--, str++) for (; *str; str++);
|
|
|
---- a/src/malloc/lite_malloc.c
|
|
|
-+++ b/src/malloc/lite_malloc.c
|
|
|
-@@ -8,7 +8,7 @@
|
|
|
-
|
|
|
- void *__expand_heap(size_t *);
|
|
|
-
|
|
|
--void *__simple_malloc(size_t n)
|
|
|
-+static void *__simple_malloc(size_t n)
|
|
|
- {
|
|
|
- static char *cur, *end;
|
|
|
- static volatile int lock[2];
|
|
|
---- a/src/math/__rem_pio2.c
|
|
|
-+++ b/src/math/__rem_pio2.c
|
|
|
-@@ -118,7 +118,7 @@ int __rem_pio2(double x, double *y)
|
|
|
- if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */
|
|
|
- medium:
|
|
|
- /* rint(x/(pi/2)), Assume round-to-nearest. */
|
|
|
-- fn = x*invpio2 + toint - toint;
|
|
|
-+ fn = (double_t)x*invpio2 + toint - toint;
|
|
|
- n = (int32_t)fn;
|
|
|
- r = x - fn*pio2_1;
|
|
|
- w = fn*pio2_1t; /* 1st round, good to 85 bits */
|
|
|
---- a/src/math/__rem_pio2f.c
|
|
|
-+++ b/src/math/__rem_pio2f.c
|
|
|
-@@ -51,7 +51,7 @@ int __rem_pio2f(float x, double *y)
|
|
|
- /* 25+53 bit pi is good enough for medium size */
|
|
|
- if (ix < 0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */
|
|
|
- /* Use a specialized rint() to get fn. Assume round-to-nearest. */
|
|
|
-- fn = x*invpio2 + toint - toint;
|
|
|
-+ fn = (double_t)x*invpio2 + toint - toint;
|
|
|
- n = (int32_t)fn;
|
|
|
- *y = x - fn*pio2_1 - fn*pio2_1t;
|
|
|
- return n;
|
|
|
---- /dev/null
|
|
|
-+++ b/src/math/arm/fabs.c
|
|
|
-@@ -0,0 +1,15 @@
|
|
|
-+#include <math.h>
|
|
|
-+
|
|
|
-+#if __ARM_PCS_VFP
|
|
|
-+
|
|
|
-+double fabs(double x)
|
|
|
-+{
|
|
|
-+ __asm__ ("vabs.f64 %P0, %P1" : "=w"(x) : "w"(x));
|
|
|
-+ return x;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#else
|
|
|
-+
|
|
|
-+#include "../fabs.c"
|
|
|
-+
|
|
|
-+#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/src/math/arm/fabsf.c
|
|
|
-@@ -0,0 +1,15 @@
|
|
|
-+#include <math.h>
|
|
|
-+
|
|
|
-+#if __ARM_PCS_VFP
|
|
|
-+
|
|
|
-+float fabsf(float x)
|
|
|
-+{
|
|
|
-+ __asm__ ("vabs.f32 %0, %1" : "=t"(x) : "t"(x));
|
|
|
-+ return x;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#else
|
|
|
-+
|
|
|
-+#include "../fabsf.c"
|
|
|
-+
|
|
|
-+#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/src/math/arm/sqrt.c
|
|
|
-@@ -0,0 +1,15 @@
|
|
|
-+#include <math.h>
|
|
|
-+
|
|
|
-+#if __VFP_FP__ && !__SOFTFP__
|
|
|
-+
|
|
|
-+double sqrt(double x)
|
|
|
-+{
|
|
|
-+ __asm__ ("vsqrt.f64 %P0, %P1" : "=w"(x) : "w"(x));
|
|
|
-+ return x;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#else
|
|
|
-+
|
|
|
-+#include "../sqrt.c"
|
|
|
-+
|
|
|
-+#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/src/math/arm/sqrtf.c
|
|
|
-@@ -0,0 +1,15 @@
|
|
|
-+#include <math.h>
|
|
|
-+
|
|
|
-+#if __VFP_FP__ && !__SOFTFP__
|
|
|
-+
|
|
|
-+float sqrtf(float x)
|
|
|
-+{
|
|
|
-+ __asm__ ("vsqrt.f32 %0, %1" : "=t"(x) : "t"(x));
|
|
|
-+ return x;
|
|
|
-+}
|
|
|
-+
|
|
|
-+#else
|
|
|
-+
|
|
|
-+#include "../sqrtf.c"
|
|
|
-+
|
|
|
-+#endif
|
|
|
---- a/src/math/armebhf/fabs.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../armhf/fabs.s
|
|
|
---- a/src/math/armebhf/fabsf.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../armhf/fabsf.s
|
|
|
---- a/src/math/armebhf/sqrt.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../armhf/sqrt.s
|
|
|
---- a/src/math/armebhf/sqrtf.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../armhf/sqrtf.s
|
|
|
---- a/src/math/armhf/fabs.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,7 +0,0 @@
|
|
|
--.fpu vfp
|
|
|
--.text
|
|
|
--.global fabs
|
|
|
--.type fabs,%function
|
|
|
--fabs:
|
|
|
-- vabs.f64 d0, d0
|
|
|
-- bx lr
|
|
|
---- a/src/math/armhf/fabs.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--fabs.s
|
|
|
---- a/src/math/armhf/fabsf.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,7 +0,0 @@
|
|
|
--.fpu vfp
|
|
|
--.text
|
|
|
--.global fabsf
|
|
|
--.type fabsf,%function
|
|
|
--fabsf:
|
|
|
-- vabs.f32 s0, s0
|
|
|
-- bx lr
|
|
|
---- a/src/math/armhf/fabsf.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--fabsf.s
|
|
|
---- a/src/math/armhf/sqrt.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,7 +0,0 @@
|
|
|
--.fpu vfp
|
|
|
--.text
|
|
|
--.global sqrt
|
|
|
--.type sqrt,%function
|
|
|
--sqrt:
|
|
|
-- vsqrt.f64 d0, d0
|
|
|
-- bx lr
|
|
|
---- a/src/math/armhf/sqrt.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--sqrt.s
|
|
|
---- a/src/math/armhf/sqrtf.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,7 +0,0 @@
|
|
|
--.fpu vfp
|
|
|
--.text
|
|
|
--.global sqrtf
|
|
|
--.type sqrtf,%function
|
|
|
--sqrtf:
|
|
|
-- vsqrt.f32 s0, s0
|
|
|
-- bx lr
|
|
|
---- a/src/math/armhf/sqrtf.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--sqrtf.s
|
|
|
---- a/src/math/hypot.c
|
|
|
-+++ b/src/math/hypot.c
|
|
|
-@@ -12,10 +12,10 @@ static void sq(double_t *hi, double_t *l
|
|
|
- {
|
|
|
- double_t xh, xl, xc;
|
|
|
-
|
|
|
-- xc = x*SPLIT;
|
|
|
-+ xc = (double_t)x*SPLIT;
|
|
|
- xh = x - xc + xc;
|
|
|
- xl = x - xh;
|
|
|
-- *hi = x*x;
|
|
|
-+ *hi = (double_t)x*x;
|
|
|
- *lo = xh*xh - *hi + 2*xh*xl + xl*xl;
|
|
|
- }
|
|
|
-
|
|
|
---- a/src/mman/mremap.c
|
|
|
-+++ b/src/mman/mremap.c
|
|
|
-@@ -1,17 +1,31 @@
|
|
|
-+#define _GNU_SOURCE
|
|
|
- #include <unistd.h>
|
|
|
- #include <sys/mman.h>
|
|
|
-+#include <errno.h>
|
|
|
-+#include <stdint.h>
|
|
|
- #include <stdarg.h>
|
|
|
- #include "syscall.h"
|
|
|
- #include "libc.h"
|
|
|
-
|
|
|
-+static void dummy(void) { }
|
|
|
-+weak_alias(dummy, __vm_wait);
|
|
|
-+
|
|
|
- void *__mremap(void *old_addr, size_t old_len, size_t new_len, int flags, ...)
|
|
|
- {
|
|
|
- va_list ap;
|
|
|
-- void *new_addr;
|
|
|
--
|
|
|
-- va_start(ap, flags);
|
|
|
-- new_addr = va_arg(ap, void *);
|
|
|
-- va_end(ap);
|
|
|
-+ void *new_addr = 0;
|
|
|
-+
|
|
|
-+ if (new_len >= PTRDIFF_MAX) {
|
|
|
-+ errno = ENOMEM;
|
|
|
-+ return MAP_FAILED;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ if (flags & MREMAP_FIXED) {
|
|
|
-+ __vm_wait();
|
|
|
-+ va_start(ap, flags);
|
|
|
-+ new_addr = va_arg(ap, void *);
|
|
|
-+ va_end(ap);
|
|
|
-+ }
|
|
|
-
|
|
|
- return (void *)syscall(SYS_mremap, old_addr, old_len, new_len, flags, new_addr);
|
|
|
- }
|
|
|
---- a/src/network/getifaddrs.c
|
|
|
-+++ b/src/network/getifaddrs.c
|
|
|
-@@ -162,13 +162,26 @@ static int netlink_msg_to_ifaddr(void *p
|
|
|
- for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
|
|
|
- switch (rta->rta_type) {
|
|
|
- case IFA_ADDRESS:
|
|
|
-- copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
|
|
|
-+ /* If ifa_addr is already set we, received an IFA_LOCAL before
|
|
|
-+ * so treat this as destination address */
|
|
|
-+ if (ifs->ifa.ifa_addr)
|
|
|
-+ copy_addr(&ifs->ifa.ifa_dstaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
|
|
|
-+ else
|
|
|
-+ copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
|
|
|
- break;
|
|
|
- case IFA_BROADCAST:
|
|
|
-- /* For point-to-point links this is peer, but ifa_broadaddr
|
|
|
-- * and ifa_dstaddr are union, so this works for both. */
|
|
|
- copy_addr(&ifs->ifa.ifa_broadaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
|
|
|
- break;
|
|
|
-+ case IFA_LOCAL:
|
|
|
-+ /* If ifa_addr is set and we get IFA_LOCAL, assume we have
|
|
|
-+ * a point-to-point network. Move address to correct field. */
|
|
|
-+ if (ifs->ifa.ifa_addr) {
|
|
|
-+ ifs->ifu = ifs->addr;
|
|
|
-+ ifs->ifa.ifa_dstaddr = &ifs->ifu.sa;
|
|
|
-+ memset(&ifs->addr, 0, sizeof(ifs->addr));
|
|
|
-+ }
|
|
|
-+ copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
|
|
|
-+ break;
|
|
|
- case IFA_LABEL:
|
|
|
- if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
|
|
|
- memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
|
|
|
---- a/src/network/getnameinfo.c
|
|
|
-+++ b/src/network/getnameinfo.c
|
|
|
-@@ -135,13 +135,13 @@ int getnameinfo(const struct sockaddr *r
|
|
|
- switch (af) {
|
|
|
- case AF_INET:
|
|
|
- a = (void *)&((struct sockaddr_in *)sa)->sin_addr;
|
|
|
-- if (sl != sizeof(struct sockaddr_in)) return EAI_FAMILY;
|
|
|
-+ if (sl < sizeof(struct sockaddr_in)) return EAI_FAMILY;
|
|
|
- mkptr4(ptr, a);
|
|
|
- scopeid = 0;
|
|
|
- break;
|
|
|
- case AF_INET6:
|
|
|
- a = (void *)&((struct sockaddr_in6 *)sa)->sin6_addr;
|
|
|
-- if (sl != sizeof(struct sockaddr_in6)) return EAI_FAMILY;
|
|
|
-+ if (sl < sizeof(struct sockaddr_in6)) return EAI_FAMILY;
|
|
|
- if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12))
|
|
|
- mkptr6(ptr, a);
|
|
|
- else
|
|
|
---- a/src/network/if_nametoindex.c
|
|
|
-+++ b/src/network/if_nametoindex.c
|
|
|
-@@ -10,7 +10,7 @@ unsigned if_nametoindex(const char *name
|
|
|
- struct ifreq ifr;
|
|
|
- int fd, r;
|
|
|
-
|
|
|
-- if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return -1;
|
|
|
-+ if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0;
|
|
|
- strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
|
|
|
- r = ioctl(fd, SIOCGIFINDEX, &ifr);
|
|
|
- __syscall(SYS_close, fd);
|
|
|
---- a/src/network/lookup.h
|
|
|
-+++ b/src/network/lookup.h
|
|
|
-@@ -2,6 +2,7 @@
|
|
|
- #define LOOKUP_H
|
|
|
-
|
|
|
- #include <stdint.h>
|
|
|
-+#include <stddef.h>
|
|
|
-
|
|
|
- struct address {
|
|
|
- int family;
|
|
|
-@@ -15,6 +16,14 @@ struct service {
|
|
|
- unsigned char proto, socktype;
|
|
|
- };
|
|
|
-
|
|
|
-+#define MAXNS 3
|
|
|
-+
|
|
|
-+struct resolvconf {
|
|
|
-+ struct address ns[MAXNS];
|
|
|
-+ unsigned nns, attempts, ndots;
|
|
|
-+ unsigned timeout;
|
|
|
-+};
|
|
|
-+
|
|
|
- /* The limit of 48 results is a non-sharp bound on the number of addresses
|
|
|
- * that can fit in one 512-byte DNS packet full of v4 results and a second
|
|
|
- * packet full of v6 results. Due to headers, the actual limit is lower. */
|
|
|
-@@ -25,4 +34,6 @@ int __lookup_serv(struct service buf[sta
|
|
|
- int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags);
|
|
|
- int __lookup_ipliteral(struct address buf[static 1], const char *name, int family);
|
|
|
-
|
|
|
-+int __get_resolv_conf(struct resolvconf *, char *, size_t);
|
|
|
-+
|
|
|
- #endif
|
|
|
---- a/src/network/lookup_name.c
|
|
|
-+++ b/src/network/lookup_name.c
|
|
|
-@@ -9,6 +9,7 @@
|
|
|
- #include <fcntl.h>
|
|
|
- #include <unistd.h>
|
|
|
- #include <pthread.h>
|
|
|
-+#include <errno.h>
|
|
|
- #include "lookup.h"
|
|
|
- #include "stdio_impl.h"
|
|
|
- #include "syscall.h"
|
|
|
-@@ -51,7 +52,14 @@ static int name_from_hosts(struct addres
|
|
|
- int cnt = 0;
|
|
|
- unsigned char _buf[1032];
|
|
|
- FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
|
|
|
-- if (!f) return 0;
|
|
|
-+ if (!f) switch (errno) {
|
|
|
-+ case ENOENT:
|
|
|
-+ case ENOTDIR:
|
|
|
-+ case EACCES:
|
|
|
-+ return 0;
|
|
|
-+ default:
|
|
|
-+ return EAI_SYSTEM;
|
|
|
-+ }
|
|
|
- while (fgets(line, sizeof line, f) && cnt < MAXADDRS) {
|
|
|
- char *p, *z;
|
|
|
-
|
|
|
-@@ -85,7 +93,7 @@ struct dpc_ctx {
|
|
|
- int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *), void *);
|
|
|
- int __dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
|
|
|
- int __res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
|
|
|
--int __res_msend(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int);
|
|
|
-+int __res_msend_rc(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int, const struct resolvconf *);
|
|
|
-
|
|
|
- #define RR_A 1
|
|
|
- #define RR_CNAME 5
|
|
|
-@@ -117,7 +125,7 @@ static int dns_parse_callback(void *c, i
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
--static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
|
|
|
-+static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, const struct resolvconf *conf)
|
|
|
- {
|
|
|
- unsigned char qbuf[2][280], abuf[2][512];
|
|
|
- const unsigned char *qp[2] = { qbuf[0], qbuf[1] };
|
|
|
-@@ -137,17 +145,59 @@ static int name_from_dns(struct address
|
|
|
- nq++;
|
|
|
- }
|
|
|
-
|
|
|
-- if (__res_msend(nq, qp, qlens, ap, alens, sizeof *abuf) < 0) return EAI_SYSTEM;
|
|
|
-+ if (__res_msend_rc(nq, qp, qlens, ap, alens, sizeof *abuf, conf) < 0)
|
|
|
-+ return EAI_SYSTEM;
|
|
|
-
|
|
|
- for (i=0; i<nq; i++)
|
|
|
- __dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);
|
|
|
-
|
|
|
- if (ctx.cnt) return ctx.cnt;
|
|
|
- if (alens[0] < 4 || (abuf[0][3] & 15) == 2) return EAI_AGAIN;
|
|
|
-- if ((abuf[0][3] & 15) == 3) return EAI_NONAME;
|
|
|
-+ if ((abuf[0][3] & 15) == 0) return EAI_NONAME;
|
|
|
-+ if ((abuf[0][3] & 15) == 3) return 0;
|
|
|
- return EAI_FAIL;
|
|
|
- }
|
|
|
-
|
|
|
-+static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
|
|
|
-+{
|
|
|
-+ char search[256];
|
|
|
-+ struct resolvconf conf;
|
|
|
-+ size_t l, dots;
|
|
|
-+ char *p, *z;
|
|
|
-+
|
|
|
-+ if (__get_resolv_conf(&conf, search, sizeof search) < 0) return -1;
|
|
|
-+
|
|
|
-+ /* Count dots, suppress search when >=ndots or name ends in
|
|
|
-+ * a dot, which is an explicit request for global scope. */
|
|
|
-+ for (dots=l=0; name[l]; l++) if (name[l]=='.') dots++;
|
|
|
-+ if (dots >= conf.ndots || name[l-1]=='.') *search = 0;
|
|
|
-+
|
|
|
-+ /* This can never happen; the caller already checked length. */
|
|
|
-+ if (l >= 256) return EAI_NONAME;
|
|
|
-+
|
|
|
-+ /* Name with search domain appended is setup in canon[]. This both
|
|
|
-+ * provides the desired default canonical name (if the requested
|
|
|
-+ * name is not a CNAME record) and serves as a buffer for passing
|
|
|
-+ * the full requested name to name_from_dns. */
|
|
|
-+ memcpy(canon, name, l);
|
|
|
-+ canon[l] = '.';
|
|
|
-+
|
|
|
-+ for (p=search; *p; p=z) {
|
|
|
-+ for (; isspace(*p); p++);
|
|
|
-+ for (z=p; *z && !isspace(*z); z++);
|
|
|
-+ if (z==p) break;
|
|
|
-+ if (z-p < 256 - l - 1) {
|
|
|
-+ memcpy(canon+l+1, p, z-p);
|
|
|
-+ canon[z-p+1+l] = 0;
|
|
|
-+ int cnt = name_from_dns(buf, canon, canon, family, &conf);
|
|
|
-+ if (cnt) return cnt;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ canon[l] = 0;
|
|
|
-+ return name_from_dns(buf, canon, name, family, &conf);
|
|
|
-+}
|
|
|
-+
|
|
|
- static const struct policy {
|
|
|
- unsigned char addr[16];
|
|
|
- unsigned char len, mask;
|
|
|
-@@ -248,7 +298,7 @@ int __lookup_name(struct address buf[sta
|
|
|
- if (!cnt) cnt = name_from_numeric(buf, name, family);
|
|
|
- if (!cnt && !(flags & AI_NUMERICHOST)) {
|
|
|
- cnt = name_from_hosts(buf, canon, name, family);
|
|
|
-- if (!cnt) cnt = name_from_dns(buf, canon, name, family);
|
|
|
-+ if (!cnt) cnt = name_from_dns_search(buf, canon, name, family);
|
|
|
- }
|
|
|
- if (cnt<=0) return cnt ? cnt : EAI_NONAME;
|
|
|
-
|
|
|
---- a/src/network/lookup_serv.c
|
|
|
-+++ b/src/network/lookup_serv.c
|
|
|
-@@ -4,6 +4,7 @@
|
|
|
- #include <ctype.h>
|
|
|
- #include <string.h>
|
|
|
- #include <fcntl.h>
|
|
|
-+#include <errno.h>
|
|
|
- #include "lookup.h"
|
|
|
- #include "stdio_impl.h"
|
|
|
-
|
|
|
-@@ -69,7 +70,14 @@ int __lookup_serv(struct service buf[sta
|
|
|
-
|
|
|
- unsigned char _buf[1032];
|
|
|
- FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
|
|
|
-- if (!f) return EAI_SERVICE;
|
|
|
-+ if (!f) switch (errno) {
|
|
|
-+ case ENOENT:
|
|
|
-+ case ENOTDIR:
|
|
|
-+ case EACCES:
|
|
|
-+ return EAI_SERVICE;
|
|
|
-+ default:
|
|
|
-+ return EAI_SYSTEM;
|
|
|
-+ }
|
|
|
-
|
|
|
- while (fgets(line, sizeof line, f) && cnt < MAXSERVS) {
|
|
|
- if ((p=strchr(line, '#'))) *p++='\n', *p=0;
|
|
|
---- a/src/network/proto.c
|
|
|
-+++ b/src/network/proto.c
|
|
|
-@@ -9,21 +9,36 @@ static const unsigned char protos[] = {
|
|
|
- "\001icmp\0"
|
|
|
- "\002igmp\0"
|
|
|
- "\003ggp\0"
|
|
|
-+ "\004ipencap\0"
|
|
|
-+ "\005st\0"
|
|
|
- "\006tcp\0"
|
|
|
-+ "\008egp\0"
|
|
|
- "\014pup\0"
|
|
|
- "\021udp\0"
|
|
|
-- "\026idp\0"
|
|
|
-+ "\024hmp\0"
|
|
|
-+ "\026xns-idp\0"
|
|
|
-+ "\033rdp\0"
|
|
|
-+ "\035iso-tp4\0"
|
|
|
-+ "\044xtp\0"
|
|
|
-+ "\045ddp\0"
|
|
|
-+ "\046idpr-cmtp\0"
|
|
|
- "\051ipv6\0"
|
|
|
- "\053ipv6-route\0"
|
|
|
- "\054ipv6-frag\0"
|
|
|
-+ "\055idrp\0"
|
|
|
-+ "\056rsvp\0"
|
|
|
- "\057gre\0"
|
|
|
- "\062esp\0"
|
|
|
- "\063ah\0"
|
|
|
-+ "\071skip\0"
|
|
|
- "\072ipv6-icmp\0"
|
|
|
- "\073ipv6-nonxt\0"
|
|
|
- "\074ipv6-opts\0"
|
|
|
-+ "\111rspf\0"
|
|
|
-+ "\121vmtp\0"
|
|
|
- "\131ospf\0"
|
|
|
- "\136ipip\0"
|
|
|
-+ "\142encap\0"
|
|
|
- "\147pim\0"
|
|
|
- "\377raw"
|
|
|
- };
|
|
|
---- a/src/network/res_msend.c
|
|
|
-+++ b/src/network/res_msend.c
|
|
|
-@@ -27,18 +27,16 @@ static unsigned long mtime()
|
|
|
- + ts.tv_nsec / 1000000;
|
|
|
- }
|
|
|
-
|
|
|
--int __res_msend(int nqueries, const unsigned char *const *queries,
|
|
|
-- const int *qlens, unsigned char *const *answers, int *alens, int asize)
|
|
|
-+int __res_msend_rc(int nqueries, const unsigned char *const *queries,
|
|
|
-+ const int *qlens, unsigned char *const *answers, int *alens, int asize,
|
|
|
-+ const struct resolvconf *conf)
|
|
|
- {
|
|
|
- int fd;
|
|
|
-- FILE *f, _f;
|
|
|
-- unsigned char _buf[256];
|
|
|
-- char line[64], *s, *z;
|
|
|
-- int timeout = 5000, attempts = 2, retry_interval, servfail_retry;
|
|
|
-+ int timeout, attempts, retry_interval, servfail_retry;
|
|
|
- union {
|
|
|
- struct sockaddr_in sin;
|
|
|
- struct sockaddr_in6 sin6;
|
|
|
-- } sa = {0}, ns[3] = {{0}};
|
|
|
-+ } sa = {0}, ns[MAXNS] = {{0}};
|
|
|
- socklen_t sl = sizeof sa.sin;
|
|
|
- int nns = 0;
|
|
|
- int family = AF_INET;
|
|
|
-@@ -48,57 +46,27 @@ int __res_msend(int nqueries, const unsi
|
|
|
- int cs;
|
|
|
- struct pollfd pfd;
|
|
|
- unsigned long t0, t1, t2;
|
|
|
-- struct address iplit;
|
|
|
-
|
|
|
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
|
|
|
-
|
|
|
-- /* Get nameservers from resolv.conf, fallback to localhost */
|
|
|
-- f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
|
|
|
-- if (f) for (nns=0; nns<3 && fgets(line, sizeof line, f); ) {
|
|
|
-- if (!strncmp(line, "options", 7) && isspace(line[7])) {
|
|
|
-- unsigned long x;
|
|
|
-- char *p, *z;
|
|
|
-- p = strstr(line, "timeout:");
|
|
|
-- if (p && isdigit(p[8])) {
|
|
|
-- p += 8;
|
|
|
-- x = strtoul(p, &z, 10);
|
|
|
-- if (z != p) timeout = x < 30 ? x*1000 : 30000;
|
|
|
-- }
|
|
|
-- p = strstr(line, "attempts:");
|
|
|
-- if (p && isdigit(p[9])) {
|
|
|
-- p += 9;
|
|
|
-- x = strtoul(p, &z, 10);
|
|
|
-- if (z != p) attempts = x < 10 ? x : 10;
|
|
|
-- if (!attempts) attempts = 1;
|
|
|
-- }
|
|
|
-- }
|
|
|
-- if (strncmp(line, "nameserver", 10) || !isspace(line[10]))
|
|
|
-- continue;
|
|
|
-- for (s=line+11; isspace(*s); s++);
|
|
|
-- for (z=s; *z && !isspace(*z); z++);
|
|
|
-- *z=0;
|
|
|
-+ timeout = 1000*conf->timeout;
|
|
|
-+ attempts = conf->attempts;
|
|
|
-
|
|
|
-- if (__lookup_ipliteral(&iplit, s, AF_UNSPEC)>0) {
|
|
|
-- if (iplit.family == AF_INET) {
|
|
|
-- memcpy(&ns[nns].sin.sin_addr, iplit.addr, 4);
|
|
|
-- ns[nns].sin.sin_port = htons(53);
|
|
|
-- ns[nns++].sin.sin_family = AF_INET;
|
|
|
-- } else {
|
|
|
-- sl = sizeof sa.sin6;
|
|
|
-- memcpy(&ns[nns].sin6.sin6_addr, iplit.addr, 16);
|
|
|
-- ns[nns].sin6.sin6_port = htons(53);
|
|
|
-- ns[nns].sin6.sin6_scope_id = iplit.scopeid;
|
|
|
-- ns[nns++].sin6.sin6_family = family = AF_INET6;
|
|
|
-- }
|
|
|
-+ nns = conf->nns;
|
|
|
-+ for (nns=0; nns<conf->nns; nns++) {
|
|
|
-+ const struct address *iplit = &conf->ns[nns];
|
|
|
-+ if (iplit->family == AF_INET) {
|
|
|
-+ memcpy(&ns[nns].sin.sin_addr, iplit->addr, 4);
|
|
|
-+ ns[nns].sin.sin_port = htons(53);
|
|
|
-+ ns[nns].sin.sin_family = AF_INET;
|
|
|
-+ } else {
|
|
|
-+ sl = sizeof sa.sin6;
|
|
|
-+ memcpy(&ns[nns].sin6.sin6_addr, iplit->addr, 16);
|
|
|
-+ ns[nns].sin6.sin6_port = htons(53);
|
|
|
-+ ns[nns].sin6.sin6_scope_id = iplit->scopeid;
|
|
|
-+ ns[nns].sin6.sin6_family = family = AF_INET6;
|
|
|
- }
|
|
|
- }
|
|
|
-- if (f) __fclose_ca(f);
|
|
|
-- if (!nns) {
|
|
|
-- ns[0].sin.sin_family = AF_INET;
|
|
|
-- ns[0].sin.sin_port = htons(53);
|
|
|
-- ns[0].sin.sin_addr.s_addr = htonl(0x7f000001);
|
|
|
-- nns=1;
|
|
|
-- }
|
|
|
-
|
|
|
- /* Get local address and open/bind a socket */
|
|
|
- sa.sin.sin_family = family;
|
|
|
-@@ -207,3 +175,11 @@ out:
|
|
|
-
|
|
|
- return 0;
|
|
|
- }
|
|
|
-+
|
|
|
-+int __res_msend(int nqueries, const unsigned char *const *queries,
|
|
|
-+ const int *qlens, unsigned char *const *answers, int *alens, int asize)
|
|
|
-+{
|
|
|
-+ struct resolvconf conf;
|
|
|
-+ if (__get_resolv_conf(&conf, 0, 0) < 0) return -1;
|
|
|
-+ return __res_msend_rc(nqueries, queries, qlens, answers, alens, asize, &conf);
|
|
|
-+}
|
|
|
---- /dev/null
|
|
|
-+++ b/src/network/resolvconf.c
|
|
|
-@@ -0,0 +1,93 @@
|
|
|
-+#include "lookup.h"
|
|
|
-+#include "stdio_impl.h"
|
|
|
-+#include <ctype.h>
|
|
|
-+#include <errno.h>
|
|
|
-+#include <string.h>
|
|
|
-+#include <netinet/in.h>
|
|
|
-+
|
|
|
-+int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
|
|
|
-+{
|
|
|
-+ char line[256];
|
|
|
-+ unsigned char _buf[256];
|
|
|
-+ FILE *f, _f;
|
|
|
-+ int nns = 0;
|
|
|
-+
|
|
|
-+ conf->ndots = 1;
|
|
|
-+ conf->timeout = 5;
|
|
|
-+ conf->attempts = 2;
|
|
|
-+ if (search) *search = 0;
|
|
|
-+
|
|
|
-+ f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
|
|
|
-+ if (!f) switch (errno) {
|
|
|
-+ case ENOENT:
|
|
|
-+ case ENOTDIR:
|
|
|
-+ case EACCES:
|
|
|
-+ goto no_resolv_conf;
|
|
|
-+ default:
|
|
|
-+ return -1;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ while (fgets(line, sizeof line, f)) {
|
|
|
-+ char *p, *z;
|
|
|
-+ if (!strchr(line, '\n') && !feof(f)) {
|
|
|
-+ /* Ignore lines that get truncated rather than
|
|
|
-+ * potentially misinterpreting them. */
|
|
|
-+ int c;
|
|
|
-+ do c = getc(f);
|
|
|
-+ while (c != '\n' && c != EOF);
|
|
|
-+ continue;
|
|
|
-+ }
|
|
|
-+ if (!strncmp(line, "options", 7) && isspace(line[7])) {
|
|
|
-+ p = strstr(line, "ndots:");
|
|
|
-+ if (p && isdigit(p[6])) {
|
|
|
-+ p += 6;
|
|
|
-+ unsigned long x = strtoul(p, &z, 10);
|
|
|
-+ if (z != p) conf->ndots = x > 15 ? 15 : x;
|
|
|
-+ }
|
|
|
-+ p = strstr(line, "attempts:");
|
|
|
-+ if (p && isdigit(p[6])) {
|
|
|
-+ p += 6;
|
|
|
-+ unsigned long x = strtoul(p, &z, 10);
|
|
|
-+ if (z != p) conf->attempts = x > 10 ? 10 : x;
|
|
|
-+ }
|
|
|
-+ p = strstr(line, "timeout:");
|
|
|
-+ if (p && (isdigit(p[8]) || p[8]=='.')) {
|
|
|
-+ p += 8;
|
|
|
-+ unsigned long x = strtoul(p, &z, 10);
|
|
|
-+ if (z != p) conf->timeout = x > 60 ? 60 : x;
|
|
|
-+ }
|
|
|
-+ continue;
|
|
|
-+ }
|
|
|
-+ if (!strncmp(line, "nameserver", 10) && isspace(line[10])) {
|
|
|
-+ if (nns >= MAXNS) continue;
|
|
|
-+ for (p=line+11; isspace(*p); p++);
|
|
|
-+ for (z=p; *z && !isspace(*z); z++);
|
|
|
-+ *z=0;
|
|
|
-+ if (__lookup_ipliteral(conf->ns+nns, p, AF_UNSPEC) > 0)
|
|
|
-+ nns++;
|
|
|
-+ continue;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ if (!search) continue;
|
|
|
-+ if ((strncmp(line, "domain", 6) && strncmp(line, "search", 6))
|
|
|
-+ || !isspace(line[6]))
|
|
|
-+ continue;
|
|
|
-+ for (p=line+7; isspace(*p); p++);
|
|
|
-+ size_t l = strlen(p);
|
|
|
-+ /* This can never happen anyway with chosen buffer sizes. */
|
|
|
-+ if (l >= search_sz) continue;
|
|
|
-+ memcpy(search, p, l+1);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ __fclose_ca(f);
|
|
|
-+
|
|
|
-+no_resolv_conf:
|
|
|
-+ if (!nns) {
|
|
|
-+ __lookup_ipliteral(conf->ns, "127.0.0.1", AF_UNSPEC);
|
|
|
-+ nns = 1;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ conf->nns = nns;
|
|
|
-+
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
---- a/src/search/tsearch_avl.c
|
|
|
-+++ b/src/search/tsearch_avl.c
|
|
|
-@@ -77,38 +77,45 @@ static struct node *find(struct node *n,
|
|
|
- return find(n->right, k, cmp);
|
|
|
- }
|
|
|
-
|
|
|
--static struct node *insert(struct node **n, const void *k,
|
|
|
-- int (*cmp)(const void *, const void *), int *new)
|
|
|
-+static struct node *insert(struct node *n, const void *k,
|
|
|
-+ int (*cmp)(const void *, const void *), struct node **found)
|
|
|
- {
|
|
|
-- struct node *r = *n;
|
|
|
-+ struct node *r;
|
|
|
- int c;
|
|
|
-
|
|
|
-- if (!r) {
|
|
|
-- *n = r = malloc(sizeof **n);
|
|
|
-- if (r) {
|
|
|
-- r->key = k;
|
|
|
-- r->left = r->right = 0;
|
|
|
-- r->height = 1;
|
|
|
-+ if (!n) {
|
|
|
-+ n = malloc(sizeof *n);
|
|
|
-+ if (n) {
|
|
|
-+ n->key = k;
|
|
|
-+ n->left = n->right = 0;
|
|
|
-+ n->height = 1;
|
|
|
- }
|
|
|
-- *new = 1;
|
|
|
-- return r;
|
|
|
-+ *found = n;
|
|
|
-+ return n;
|
|
|
-+ }
|
|
|
-+ c = cmp(k, n->key);
|
|
|
-+ if (c == 0) {
|
|
|
-+ *found = n;
|
|
|
-+ return 0;
|
|
|
-+ }
|
|
|
-+ r = insert(c < 0 ? n->left : n->right, k, cmp, found);
|
|
|
-+ if (r) {
|
|
|
-+ if (c < 0)
|
|
|
-+ n->left = r;
|
|
|
-+ else
|
|
|
-+ n->right = r;
|
|
|
-+ r = balance(n);
|
|
|
- }
|
|
|
-- c = cmp(k, r->key);
|
|
|
-- if (c == 0)
|
|
|
-- return r;
|
|
|
-- if (c < 0)
|
|
|
-- r = insert(&r->left, k, cmp, new);
|
|
|
-- else
|
|
|
-- r = insert(&r->right, k, cmp, new);
|
|
|
-- if (*new)
|
|
|
-- *n = balance(*n);
|
|
|
- return r;
|
|
|
- }
|
|
|
-
|
|
|
--static struct node *movr(struct node *n, struct node *r) {
|
|
|
-- if (!n)
|
|
|
-- return r;
|
|
|
-- n->right = movr(n->right, r);
|
|
|
-+static struct node *remove_rightmost(struct node *n, struct node **rightmost)
|
|
|
-+{
|
|
|
-+ if (!n->right) {
|
|
|
-+ *rightmost = n;
|
|
|
-+ return n->left;
|
|
|
-+ }
|
|
|
-+ n->right = remove_rightmost(n->right, rightmost);
|
|
|
- return balance(n);
|
|
|
- }
|
|
|
-
|
|
|
-@@ -122,7 +129,13 @@ static struct node *remove(struct node *
|
|
|
- c = cmp(k, (*n)->key);
|
|
|
- if (c == 0) {
|
|
|
- struct node *r = *n;
|
|
|
-- *n = movr(r->left, r->right);
|
|
|
-+ if (r->left) {
|
|
|
-+ r->left = remove_rightmost(r->left, n);
|
|
|
-+ (*n)->left = r->left;
|
|
|
-+ (*n)->right = r->right;
|
|
|
-+ *n = balance(*n);
|
|
|
-+ } else
|
|
|
-+ *n = r->right;
|
|
|
- free(r);
|
|
|
- return parent;
|
|
|
- }
|
|
|
-@@ -138,6 +151,8 @@ static struct node *remove(struct node *
|
|
|
- void *tdelete(const void *restrict key, void **restrict rootp,
|
|
|
- int(*compar)(const void *, const void *))
|
|
|
- {
|
|
|
-+ if (!rootp)
|
|
|
-+ return 0;
|
|
|
- struct node *n = *rootp;
|
|
|
- struct node *ret;
|
|
|
- /* last argument is arbitrary non-null pointer
|
|
|
-@@ -150,17 +165,21 @@ void *tdelete(const void *restrict key,
|
|
|
- void *tfind(const void *key, void *const *rootp,
|
|
|
- int(*compar)(const void *, const void *))
|
|
|
- {
|
|
|
-+ if (!rootp)
|
|
|
-+ return 0;
|
|
|
- return find(*rootp, key, compar);
|
|
|
- }
|
|
|
-
|
|
|
- void *tsearch(const void *key, void **rootp,
|
|
|
- int (*compar)(const void *, const void *))
|
|
|
- {
|
|
|
-- int new = 0;
|
|
|
-- struct node *n = *rootp;
|
|
|
-+ struct node *update;
|
|
|
- struct node *ret;
|
|
|
-- ret = insert(&n, key, compar, &new);
|
|
|
-- *rootp = n;
|
|
|
-+ if (!rootp)
|
|
|
-+ return 0;
|
|
|
-+ update = insert(*rootp, key, compar, &ret);
|
|
|
-+ if (update)
|
|
|
-+ *rootp = update;
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
---- a/src/setjmp/arm/longjmp.s
|
|
|
-+++ b/src/setjmp/arm/longjmp.s
|
|
|
-@@ -1,3 +1,4 @@
|
|
|
-+.syntax unified
|
|
|
- .global _longjmp
|
|
|
- .global longjmp
|
|
|
- .type _longjmp,%function
|
|
|
-@@ -20,7 +21,11 @@ longjmp:
|
|
|
- ldc p2, cr4, [ip], #48
|
|
|
- 2: tst r1,#0x40
|
|
|
- beq 2f
|
|
|
-- .word 0xecbc8b10 /* vldmia ip!, {d8-d15} */
|
|
|
-+ .fpu vfp
|
|
|
-+ vldmia ip!, {d8-d15}
|
|
|
-+ .fpu softvfp
|
|
|
-+ .eabi_attribute 10, 0
|
|
|
-+ .eabi_attribute 27, 0
|
|
|
- 2: tst r1,#0x200
|
|
|
- beq 3f
|
|
|
- ldcl p1, cr10, [ip], #8
|
|
|
-@@ -29,9 +34,7 @@ longjmp:
|
|
|
- ldcl p1, cr13, [ip], #8
|
|
|
- ldcl p1, cr14, [ip], #8
|
|
|
- ldcl p1, cr15, [ip], #8
|
|
|
--3: tst lr,#1
|
|
|
-- moveq pc,lr
|
|
|
-- bx lr
|
|
|
-+3: bx lr
|
|
|
-
|
|
|
- .hidden __hwcap
|
|
|
- 1: .word __hwcap-1b
|
|
|
---- a/src/setjmp/arm/setjmp.s
|
|
|
-+++ b/src/setjmp/arm/setjmp.s
|
|
|
-@@ -1,3 +1,4 @@
|
|
|
-+.syntax unified
|
|
|
- .global __setjmp
|
|
|
- .global _setjmp
|
|
|
- .global setjmp
|
|
|
-@@ -22,7 +23,11 @@ setjmp:
|
|
|
- stc p2, cr4, [ip], #48
|
|
|
- 2: tst r1,#0x40
|
|
|
- beq 2f
|
|
|
-- .word 0xecac8b10 /* vstmia ip!, {d8-d15} */
|
|
|
-+ .fpu vfp
|
|
|
-+ vstmia ip!, {d8-d15}
|
|
|
-+ .fpu softvfp
|
|
|
-+ .eabi_attribute 10, 0
|
|
|
-+ .eabi_attribute 27, 0
|
|
|
- 2: tst r1,#0x200
|
|
|
- beq 3f
|
|
|
- stcl p1, cr10, [ip], #8
|
|
|
-@@ -31,9 +36,7 @@ setjmp:
|
|
|
- stcl p1, cr13, [ip], #8
|
|
|
- stcl p1, cr14, [ip], #8
|
|
|
- stcl p1, cr15, [ip], #8
|
|
|
--3: tst lr,#1
|
|
|
-- moveq pc,lr
|
|
|
-- bx lr
|
|
|
-+3: bx lr
|
|
|
-
|
|
|
- .hidden __hwcap
|
|
|
- 1: .word __hwcap-1b
|
|
|
---- a/src/setjmp/mips-sf/longjmp.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,25 +0,0 @@
|
|
|
--.set noreorder
|
|
|
--
|
|
|
--.global _longjmp
|
|
|
--.global longjmp
|
|
|
--.type _longjmp,@function
|
|
|
--.type longjmp,@function
|
|
|
--_longjmp:
|
|
|
--longjmp:
|
|
|
-- move $2, $5
|
|
|
-- bne $2, $0, 1f
|
|
|
-- nop
|
|
|
-- addu $2, $2, 1
|
|
|
--1: lw $ra, 0($4)
|
|
|
-- lw $sp, 4($4)
|
|
|
-- lw $16, 8($4)
|
|
|
-- lw $17, 12($4)
|
|
|
-- lw $18, 16($4)
|
|
|
-- lw $19, 20($4)
|
|
|
-- lw $20, 24($4)
|
|
|
-- lw $21, 28($4)
|
|
|
-- lw $22, 32($4)
|
|
|
-- lw $23, 36($4)
|
|
|
-- lw $30, 40($4)
|
|
|
-- jr $ra
|
|
|
-- lw $28, 44($4)
|
|
|
---- a/src/setjmp/mips-sf/longjmp.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--longjmp.s
|
|
|
---- a/src/setjmp/mips-sf/setjmp.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,25 +0,0 @@
|
|
|
--.set noreorder
|
|
|
--
|
|
|
--.global __setjmp
|
|
|
--.global _setjmp
|
|
|
--.global setjmp
|
|
|
--.type __setjmp,@function
|
|
|
--.type _setjmp,@function
|
|
|
--.type setjmp,@function
|
|
|
--__setjmp:
|
|
|
--_setjmp:
|
|
|
--setjmp:
|
|
|
-- sw $ra, 0($4)
|
|
|
-- sw $sp, 4($4)
|
|
|
-- sw $16, 8($4)
|
|
|
-- sw $17, 12($4)
|
|
|
-- sw $18, 16($4)
|
|
|
-- sw $19, 20($4)
|
|
|
-- sw $20, 24($4)
|
|
|
-- sw $21, 28($4)
|
|
|
-- sw $22, 32($4)
|
|
|
-- sw $23, 36($4)
|
|
|
-- sw $30, 40($4)
|
|
|
-- sw $28, 44($4)
|
|
|
-- jr $ra
|
|
|
-- li $2, 0
|
|
|
---- a/src/setjmp/mips-sf/setjmp.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--setjmp.s
|
|
|
---- /dev/null
|
|
|
-+++ b/src/setjmp/mips/longjmp.S
|
|
|
-@@ -0,0 +1,40 @@
|
|
|
-+.set noreorder
|
|
|
-+
|
|
|
-+.global _longjmp
|
|
|
-+.global longjmp
|
|
|
-+.type _longjmp,@function
|
|
|
-+.type longjmp,@function
|
|
|
-+_longjmp:
|
|
|
-+longjmp:
|
|
|
-+ move $2, $5
|
|
|
-+ bne $2, $0, 1f
|
|
|
-+ nop
|
|
|
-+ addu $2, $2, 1
|
|
|
-+1:
|
|
|
-+#ifndef __mips_soft_float
|
|
|
-+ lwc1 $20, 56($4)
|
|
|
-+ lwc1 $21, 60($4)
|
|
|
-+ lwc1 $22, 64($4)
|
|
|
-+ lwc1 $23, 68($4)
|
|
|
-+ lwc1 $24, 72($4)
|
|
|
-+ lwc1 $25, 76($4)
|
|
|
-+ lwc1 $26, 80($4)
|
|
|
-+ lwc1 $27, 84($4)
|
|
|
-+ lwc1 $28, 88($4)
|
|
|
-+ lwc1 $29, 92($4)
|
|
|
-+ lwc1 $30, 96($4)
|
|
|
-+ lwc1 $31, 100($4)
|
|
|
-+#endif
|
|
|
-+ lw $ra, 0($4)
|
|
|
-+ lw $sp, 4($4)
|
|
|
-+ lw $16, 8($4)
|
|
|
-+ lw $17, 12($4)
|
|
|
-+ lw $18, 16($4)
|
|
|
-+ lw $19, 20($4)
|
|
|
-+ lw $20, 24($4)
|
|
|
-+ lw $21, 28($4)
|
|
|
-+ lw $22, 32($4)
|
|
|
-+ lw $23, 36($4)
|
|
|
-+ lw $30, 40($4)
|
|
|
-+ jr $ra
|
|
|
-+ lw $28, 44($4)
|
|
|
---- a/src/setjmp/mips/longjmp.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,37 +0,0 @@
|
|
|
--.set noreorder
|
|
|
--
|
|
|
--.global _longjmp
|
|
|
--.global longjmp
|
|
|
--.type _longjmp,@function
|
|
|
--.type longjmp,@function
|
|
|
--_longjmp:
|
|
|
--longjmp:
|
|
|
-- move $2, $5
|
|
|
-- bne $2, $0, 1f
|
|
|
-- nop
|
|
|
-- addu $2, $2, 1
|
|
|
--1: lwc1 $20, 56($4)
|
|
|
-- lwc1 $21, 60($4)
|
|
|
-- lwc1 $22, 64($4)
|
|
|
-- lwc1 $23, 68($4)
|
|
|
-- lwc1 $24, 72($4)
|
|
|
-- lwc1 $25, 76($4)
|
|
|
-- lwc1 $26, 80($4)
|
|
|
-- lwc1 $27, 84($4)
|
|
|
-- lwc1 $28, 88($4)
|
|
|
-- lwc1 $29, 92($4)
|
|
|
-- lwc1 $30, 96($4)
|
|
|
-- lwc1 $31, 100($4)
|
|
|
-- lw $ra, 0($4)
|
|
|
-- lw $sp, 4($4)
|
|
|
-- lw $16, 8($4)
|
|
|
-- lw $17, 12($4)
|
|
|
-- lw $18, 16($4)
|
|
|
-- lw $19, 20($4)
|
|
|
-- lw $20, 24($4)
|
|
|
-- lw $21, 28($4)
|
|
|
-- lw $22, 32($4)
|
|
|
-- lw $23, 36($4)
|
|
|
-- lw $30, 40($4)
|
|
|
-- jr $ra
|
|
|
-- lw $28, 44($4)
|
|
|
---- /dev/null
|
|
|
-+++ b/src/setjmp/mips/setjmp.S
|
|
|
-@@ -0,0 +1,39 @@
|
|
|
-+.set noreorder
|
|
|
-+
|
|
|
-+.global __setjmp
|
|
|
-+.global _setjmp
|
|
|
-+.global setjmp
|
|
|
-+.type __setjmp,@function
|
|
|
-+.type _setjmp,@function
|
|
|
-+.type setjmp,@function
|
|
|
-+__setjmp:
|
|
|
-+_setjmp:
|
|
|
-+setjmp:
|
|
|
-+ sw $ra, 0($4)
|
|
|
-+ sw $sp, 4($4)
|
|
|
-+ sw $16, 8($4)
|
|
|
-+ sw $17, 12($4)
|
|
|
-+ sw $18, 16($4)
|
|
|
-+ sw $19, 20($4)
|
|
|
-+ sw $20, 24($4)
|
|
|
-+ sw $21, 28($4)
|
|
|
-+ sw $22, 32($4)
|
|
|
-+ sw $23, 36($4)
|
|
|
-+ sw $30, 40($4)
|
|
|
-+ sw $28, 44($4)
|
|
|
-+#ifndef __mips_soft_float
|
|
|
-+ swc1 $20, 56($4)
|
|
|
-+ swc1 $21, 60($4)
|
|
|
-+ swc1 $22, 64($4)
|
|
|
-+ swc1 $23, 68($4)
|
|
|
-+ swc1 $24, 72($4)
|
|
|
-+ swc1 $25, 76($4)
|
|
|
-+ swc1 $26, 80($4)
|
|
|
-+ swc1 $27, 84($4)
|
|
|
-+ swc1 $28, 88($4)
|
|
|
-+ swc1 $29, 92($4)
|
|
|
-+ swc1 $30, 96($4)
|
|
|
-+ swc1 $31, 100($4)
|
|
|
-+#endif
|
|
|
-+ jr $ra
|
|
|
-+ li $2, 0
|
|
|
---- a/src/setjmp/mips/setjmp.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,37 +0,0 @@
|
|
|
--.set noreorder
|
|
|
--
|
|
|
--.global __setjmp
|
|
|
--.global _setjmp
|
|
|
--.global setjmp
|
|
|
--.type __setjmp,@function
|
|
|
--.type _setjmp,@function
|
|
|
--.type setjmp,@function
|
|
|
--__setjmp:
|
|
|
--_setjmp:
|
|
|
--setjmp:
|
|
|
-- sw $ra, 0($4)
|
|
|
-- sw $sp, 4($4)
|
|
|
-- sw $16, 8($4)
|
|
|
-- sw $17, 12($4)
|
|
|
-- sw $18, 16($4)
|
|
|
-- sw $19, 20($4)
|
|
|
-- sw $20, 24($4)
|
|
|
-- sw $21, 28($4)
|
|
|
-- sw $22, 32($4)
|
|
|
-- sw $23, 36($4)
|
|
|
-- sw $30, 40($4)
|
|
|
-- sw $28, 44($4)
|
|
|
-- swc1 $20, 56($4)
|
|
|
-- swc1 $21, 60($4)
|
|
|
-- swc1 $22, 64($4)
|
|
|
-- swc1 $23, 68($4)
|
|
|
-- swc1 $24, 72($4)
|
|
|
-- swc1 $25, 76($4)
|
|
|
-- swc1 $26, 80($4)
|
|
|
-- swc1 $27, 84($4)
|
|
|
-- swc1 $28, 88($4)
|
|
|
-- swc1 $29, 92($4)
|
|
|
-- swc1 $30, 96($4)
|
|
|
-- swc1 $31, 100($4)
|
|
|
-- jr $ra
|
|
|
-- li $2, 0
|
|
|
---- a/src/setjmp/mipsel-sf/longjmp.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../mips-sf/longjmp.s
|
|
|
---- a/src/setjmp/mipsel-sf/setjmp.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../mips-sf/setjmp.s
|
|
|
---- a/src/setjmp/sh-nofpu/longjmp.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,22 +0,0 @@
|
|
|
--.global _longjmp
|
|
|
--.global longjmp
|
|
|
--.type _longjmp, @function
|
|
|
--.type longjmp, @function
|
|
|
--_longjmp:
|
|
|
--longjmp:
|
|
|
-- mov.l @r4+, r8
|
|
|
-- mov.l @r4+, r9
|
|
|
-- mov.l @r4+, r10
|
|
|
-- mov.l @r4+, r11
|
|
|
-- mov.l @r4+, r12
|
|
|
-- mov.l @r4+, r13
|
|
|
-- mov.l @r4+, r14
|
|
|
-- mov.l @r4+, r15
|
|
|
-- lds.l @r4+, pr
|
|
|
--
|
|
|
-- tst r5, r5
|
|
|
-- movt r0
|
|
|
-- add r5, r0
|
|
|
--
|
|
|
-- rts
|
|
|
-- nop
|
|
|
---- a/src/setjmp/sh-nofpu/longjmp.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--longjmp.s
|
|
|
---- a/src/setjmp/sh-nofpu/setjmp.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,24 +0,0 @@
|
|
|
--.global ___setjmp
|
|
|
--.hidden ___setjmp
|
|
|
--.global __setjmp
|
|
|
--.global _setjmp
|
|
|
--.global setjmp
|
|
|
--.type __setjmp, @function
|
|
|
--.type _setjmp, @function
|
|
|
--.type setjmp, @function
|
|
|
--___setjmp:
|
|
|
--__setjmp:
|
|
|
--_setjmp:
|
|
|
--setjmp:
|
|
|
-- add #36, r4
|
|
|
-- sts.l pr, @-r4
|
|
|
-- mov.l r15 @-r4
|
|
|
-- mov.l r14, @-r4
|
|
|
-- mov.l r13, @-r4
|
|
|
-- mov.l r12, @-r4
|
|
|
-- mov.l r11, @-r4
|
|
|
-- mov.l r10, @-r4
|
|
|
-- mov.l r9, @-r4
|
|
|
-- mov.l r8, @-r4
|
|
|
-- rts
|
|
|
-- mov #0, r0
|
|
|
---- a/src/setjmp/sh-nofpu/setjmp.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--setjmp.s
|
|
|
---- /dev/null
|
|
|
-+++ b/src/setjmp/sh/longjmp.S
|
|
|
-@@ -0,0 +1,28 @@
|
|
|
-+.global _longjmp
|
|
|
-+.global longjmp
|
|
|
-+.type _longjmp, @function
|
|
|
-+.type longjmp, @function
|
|
|
-+_longjmp:
|
|
|
-+longjmp:
|
|
|
-+ mov.l @r4+, r8
|
|
|
-+ mov.l @r4+, r9
|
|
|
-+ mov.l @r4+, r10
|
|
|
-+ mov.l @r4+, r11
|
|
|
-+ mov.l @r4+, r12
|
|
|
-+ mov.l @r4+, r13
|
|
|
-+ mov.l @r4+, r14
|
|
|
-+ mov.l @r4+, r15
|
|
|
-+ lds.l @r4+, pr
|
|
|
-+#if __SH_FPU_ANY__ || __SH4__
|
|
|
-+ fmov.s @r4+, fr12
|
|
|
-+ fmov.s @r4+, fr13
|
|
|
-+ fmov.s @r4+, fr14
|
|
|
-+ fmov.s @r4+, fr15
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+ tst r5, r5
|
|
|
-+ movt r0
|
|
|
-+ add r5, r0
|
|
|
-+
|
|
|
-+ rts
|
|
|
-+ nop
|
|
|
---- a/src/setjmp/sh/longjmp.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,26 +0,0 @@
|
|
|
--.global _longjmp
|
|
|
--.global longjmp
|
|
|
--.type _longjmp, @function
|
|
|
--.type longjmp, @function
|
|
|
--_longjmp:
|
|
|
--longjmp:
|
|
|
-- mov.l @r4+, r8
|
|
|
-- mov.l @r4+, r9
|
|
|
-- mov.l @r4+, r10
|
|
|
-- mov.l @r4+, r11
|
|
|
-- mov.l @r4+, r12
|
|
|
-- mov.l @r4+, r13
|
|
|
-- mov.l @r4+, r14
|
|
|
-- mov.l @r4+, r15
|
|
|
-- lds.l @r4+, pr
|
|
|
-- fmov.s @r4+, fr12
|
|
|
-- fmov.s @r4+, fr13
|
|
|
-- fmov.s @r4+, fr14
|
|
|
-- fmov.s @r4+, fr15
|
|
|
--
|
|
|
-- tst r5, r5
|
|
|
-- movt r0
|
|
|
-- add r5, r0
|
|
|
--
|
|
|
-- rts
|
|
|
-- nop
|
|
|
---- /dev/null
|
|
|
-+++ b/src/setjmp/sh/setjmp.S
|
|
|
-@@ -0,0 +1,32 @@
|
|
|
-+.global ___setjmp
|
|
|
-+.hidden ___setjmp
|
|
|
-+.global __setjmp
|
|
|
-+.global _setjmp
|
|
|
-+.global setjmp
|
|
|
-+.type __setjmp, @function
|
|
|
-+.type _setjmp, @function
|
|
|
-+.type setjmp, @function
|
|
|
-+___setjmp:
|
|
|
-+__setjmp:
|
|
|
-+_setjmp:
|
|
|
-+setjmp:
|
|
|
-+#if __SH_FPU_ANY__ || __SH4__
|
|
|
-+ add #52, r4
|
|
|
-+ fmov.s fr15, @-r4
|
|
|
-+ fmov.s fr14, @-r4
|
|
|
-+ fmov.s fr13, @-r4
|
|
|
-+ fmov.s fr12, @-r4
|
|
|
-+#else
|
|
|
-+ add #36, r4
|
|
|
-+#endif
|
|
|
-+ sts.l pr, @-r4
|
|
|
-+ mov.l r15, @-r4
|
|
|
-+ mov.l r14, @-r4
|
|
|
-+ mov.l r13, @-r4
|
|
|
-+ mov.l r12, @-r4
|
|
|
-+ mov.l r11, @-r4
|
|
|
-+ mov.l r10, @-r4
|
|
|
-+ mov.l r9, @-r4
|
|
|
-+ mov.l r8, @-r4
|
|
|
-+ rts
|
|
|
-+ mov #0, r0
|
|
|
---- a/src/setjmp/sh/setjmp.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,28 +0,0 @@
|
|
|
--.global ___setjmp
|
|
|
--.hidden ___setjmp
|
|
|
--.global __setjmp
|
|
|
--.global _setjmp
|
|
|
--.global setjmp
|
|
|
--.type __setjmp, @function
|
|
|
--.type _setjmp, @function
|
|
|
--.type setjmp, @function
|
|
|
--___setjmp:
|
|
|
--__setjmp:
|
|
|
--_setjmp:
|
|
|
--setjmp:
|
|
|
-- add #52, r4
|
|
|
-- fmov.s fr15, @-r4
|
|
|
-- fmov.s fr14, @-r4
|
|
|
-- fmov.s fr13, @-r4
|
|
|
-- fmov.s fr12, @-r4
|
|
|
-- sts.l pr, @-r4
|
|
|
-- mov.l r15, @-r4
|
|
|
-- mov.l r14, @-r4
|
|
|
-- mov.l r13, @-r4
|
|
|
-- mov.l r12, @-r4
|
|
|
-- mov.l r11, @-r4
|
|
|
-- mov.l r10, @-r4
|
|
|
-- mov.l r9, @-r4
|
|
|
-- mov.l r8, @-r4
|
|
|
-- rts
|
|
|
-- mov #0, r0
|
|
|
---- a/src/setjmp/sheb-nofpu/longjmp.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../sh-nofpu/longjmp.s
|
|
|
---- a/src/setjmp/sheb-nofpu/setjmp.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../sh-nofpu/setjmp.s
|
|
|
---- a/src/signal/arm/restore.s
|
|
|
-+++ b/src/signal/arm/restore.s
|
|
|
-@@ -1,3 +1,5 @@
|
|
|
-+.syntax unified
|
|
|
-+
|
|
|
- .global __restore
|
|
|
- .type __restore,%function
|
|
|
- __restore:
|
|
|
---- a/src/signal/arm/sigsetjmp.s
|
|
|
-+++ b/src/signal/arm/sigsetjmp.s
|
|
|
-@@ -1,3 +1,4 @@
|
|
|
-+.syntax unified
|
|
|
- .global sigsetjmp
|
|
|
- .global __sigsetjmp
|
|
|
- .type sigsetjmp,%function
|
|
|
---- a/src/signal/sigaction.c
|
|
|
-+++ b/src/signal/sigaction.c
|
|
|
-@@ -17,10 +17,6 @@ void __get_handler_set(sigset_t *set)
|
|
|
- int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
|
|
|
- {
|
|
|
- struct k_sigaction ksa, ksa_old;
|
|
|
-- if (sig >= (unsigned)_NSIG) {
|
|
|
-- errno = EINVAL;
|
|
|
-- return -1;
|
|
|
-- }
|
|
|
- if (sa) {
|
|
|
- if ((uintptr_t)sa->sa_handler > 1UL) {
|
|
|
- a_or_l(handler_set+(sig-1)/(8*sizeof(long)),
|
|
|
-@@ -57,7 +53,7 @@ int __libc_sigaction(int sig, const stru
|
|
|
-
|
|
|
- int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
|
|
|
- {
|
|
|
-- if (sig-32U < 3) {
|
|
|
-+ if (sig-32U < 3 || sig-1U >= _NSIG-1) {
|
|
|
- errno = EINVAL;
|
|
|
- return -1;
|
|
|
- }
|
|
|
---- a/src/signal/sigsetjmp_tail.c
|
|
|
-+++ b/src/signal/sigsetjmp_tail.c
|
|
|
-@@ -2,9 +2,7 @@
|
|
|
- #include <signal.h>
|
|
|
- #include "syscall.h"
|
|
|
-
|
|
|
--#ifdef SHARED
|
|
|
- __attribute__((__visibility__("hidden")))
|
|
|
--#endif
|
|
|
- int __sigsetjmp_tail(sigjmp_buf jb, int ret)
|
|
|
- {
|
|
|
- void *p = jb->__ss;
|
|
|
---- a/src/stdio/getdelim.c
|
|
|
-+++ b/src/stdio/getdelim.c
|
|
|
-@@ -27,17 +27,18 @@ ssize_t getdelim(char **restrict s, size
|
|
|
- for (;;) {
|
|
|
- z = memchr(f->rpos, delim, f->rend - f->rpos);
|
|
|
- k = z ? z - f->rpos + 1 : f->rend - f->rpos;
|
|
|
-- if (i+k >= *n) {
|
|
|
-+ if (i+k+1 >= *n) {
|
|
|
- if (k >= SIZE_MAX/2-i) goto oom;
|
|
|
-- *n = i+k+2;
|
|
|
-- if (*n < SIZE_MAX/4) *n *= 2;
|
|
|
-- tmp = realloc(*s, *n);
|
|
|
-+ size_t m = i+k+2;
|
|
|
-+ if (!z && m < SIZE_MAX/4) m += m/2;
|
|
|
-+ tmp = realloc(*s, m);
|
|
|
- if (!tmp) {
|
|
|
-- *n = i+k+2;
|
|
|
-- tmp = realloc(*s, *n);
|
|
|
-+ m = i+k+2;
|
|
|
-+ tmp = realloc(*s, m);
|
|
|
- if (!tmp) goto oom;
|
|
|
- }
|
|
|
- *s = tmp;
|
|
|
-+ *n = m;
|
|
|
- }
|
|
|
- memcpy(*s+i, f->rpos, k);
|
|
|
- f->rpos += k;
|
|
|
---- /dev/null
|
|
|
-+++ b/src/string/arm/__aeabi_memclr.c
|
|
|
-@@ -0,0 +1,9 @@
|
|
|
-+#include <string.h>
|
|
|
-+#include "libc.h"
|
|
|
-+
|
|
|
-+void __aeabi_memclr(void *dest, size_t n)
|
|
|
-+{
|
|
|
-+ memset(dest, 0, n);
|
|
|
-+}
|
|
|
-+weak_alias(__aeabi_memclr, __aeabi_memclr4);
|
|
|
-+weak_alias(__aeabi_memclr, __aeabi_memclr8);
|
|
|
---- /dev/null
|
|
|
-+++ b/src/string/arm/__aeabi_memcpy.c
|
|
|
-@@ -0,0 +1,9 @@
|
|
|
-+#include <string.h>
|
|
|
-+#include "libc.h"
|
|
|
-+
|
|
|
-+void __aeabi_memcpy(void *restrict dest, const void *restrict src, size_t n)
|
|
|
-+{
|
|
|
-+ memcpy(dest, src, n);
|
|
|
-+}
|
|
|
-+weak_alias(__aeabi_memcpy, __aeabi_memcpy4);
|
|
|
-+weak_alias(__aeabi_memcpy, __aeabi_memcpy8);
|
|
|
---- /dev/null
|
|
|
-+++ b/src/string/arm/__aeabi_memmove.c
|
|
|
-@@ -0,0 +1,9 @@
|
|
|
-+#include <string.h>
|
|
|
-+#include "libc.h"
|
|
|
-+
|
|
|
-+void __aeabi_memmove(void *dest, const void *src, size_t n)
|
|
|
-+{
|
|
|
-+ memmove(dest, src, n);
|
|
|
-+}
|
|
|
-+weak_alias(__aeabi_memmove, __aeabi_memmove4);
|
|
|
-+weak_alias(__aeabi_memmove, __aeabi_memmove8);
|
|
|
---- /dev/null
|
|
|
-+++ b/src/string/arm/__aeabi_memset.c
|
|
|
-@@ -0,0 +1,9 @@
|
|
|
-+#include <string.h>
|
|
|
-+#include "libc.h"
|
|
|
-+
|
|
|
-+void __aeabi_memset(void *dest, size_t n, int c)
|
|
|
-+{
|
|
|
-+ memset(dest, c, n);
|
|
|
-+}
|
|
|
-+weak_alias(__aeabi_memset, __aeabi_memset4);
|
|
|
-+weak_alias(__aeabi_memset, __aeabi_memset8);
|
|
|
---- /dev/null
|
|
|
-+++ b/src/string/arm/memcpy.c
|
|
|
-@@ -0,0 +1,3 @@
|
|
|
-+#if __ARMEB__
|
|
|
-+#include "../memcpy.c"
|
|
|
-+#endif
|
|
|
---- /dev/null
|
|
|
-+++ b/src/string/arm/memcpy_le.S
|
|
|
-@@ -0,0 +1,383 @@
|
|
|
-+#ifndef __ARMEB__
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Copyright (C) 2008 The Android Open Source Project
|
|
|
-+ * All rights reserved.
|
|
|
-+ *
|
|
|
-+ * Redistribution and use in source and binary forms, with or without
|
|
|
-+ * modification, are permitted provided that the following conditions
|
|
|
-+ * are met:
|
|
|
-+ * * Redistributions of source code must retain the above copyright
|
|
|
-+ * notice, this list of conditions and the following disclaimer.
|
|
|
-+ * * Redistributions in binary form must reproduce the above copyright
|
|
|
-+ * notice, this list of conditions and the following disclaimer in
|
|
|
-+ * the documentation and/or other materials provided with the
|
|
|
-+ * distribution.
|
|
|
-+ *
|
|
|
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
-+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
-+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
-+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
|
-+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
|
-+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
|
-+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
|
-+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
-+ * SUCH DAMAGE.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * Optimized memcpy() for ARM.
|
|
|
-+ *
|
|
|
-+ * note that memcpy() always returns the destination pointer,
|
|
|
-+ * so we have to preserve R0.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+/*
|
|
|
-+ * This file has been modified from the original for use in musl libc.
|
|
|
-+ * The main changes are: addition of .type memcpy,%function to make the
|
|
|
-+ * code safely callable from thumb mode, adjusting the return
|
|
|
-+ * instructions to be compatible with pre-thumb ARM cpus, and removal
|
|
|
-+ * of prefetch code that is not compatible with older cpus.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+.syntax unified
|
|
|
-+
|
|
|
-+.global memcpy
|
|
|
-+.type memcpy,%function
|
|
|
-+memcpy:
|
|
|
-+ /* The stack must always be 64-bits aligned to be compliant with the
|
|
|
-+ * ARM ABI. Since we have to save R0, we might as well save R4
|
|
|
-+ * which we can use for better pipelining of the reads below
|
|
|
-+ */
|
|
|
-+ .fnstart
|
|
|
-+ .save {r0, r4, lr}
|
|
|
-+ stmfd sp!, {r0, r4, lr}
|
|
|
-+ /* Making room for r5-r11 which will be spilled later */
|
|
|
-+ .pad #28
|
|
|
-+ sub sp, sp, #28
|
|
|
-+
|
|
|
-+ /* it simplifies things to take care of len<4 early */
|
|
|
-+ cmp r2, #4
|
|
|
-+ blo copy_last_3_and_return
|
|
|
-+
|
|
|
-+ /* compute the offset to align the source
|
|
|
-+ * offset = (4-(src&3))&3 = -src & 3
|
|
|
-+ */
|
|
|
-+ rsb r3, r1, #0
|
|
|
-+ ands r3, r3, #3
|
|
|
-+ beq src_aligned
|
|
|
-+
|
|
|
-+ /* align source to 32 bits. We need to insert 2 instructions between
|
|
|
-+ * a ldr[b|h] and str[b|h] because byte and half-word instructions
|
|
|
-+ * stall 2 cycles.
|
|
|
-+ */
|
|
|
-+ movs r12, r3, lsl #31
|
|
|
-+ sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */
|
|
|
-+ ldrbmi r3, [r1], #1
|
|
|
-+ ldrbcs r4, [r1], #1
|
|
|
-+ ldrbcs r12,[r1], #1
|
|
|
-+ strbmi r3, [r0], #1
|
|
|
-+ strbcs r4, [r0], #1
|
|
|
-+ strbcs r12,[r0], #1
|
|
|
-+
|
|
|
-+src_aligned:
|
|
|
-+
|
|
|
-+ /* see if src and dst are aligned together (congruent) */
|
|
|
-+ eor r12, r0, r1
|
|
|
-+ tst r12, #3
|
|
|
-+ bne non_congruent
|
|
|
-+
|
|
|
-+ /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
|
|
|
-+ * frame. Don't update sp.
|
|
|
-+ */
|
|
|
-+ stmea sp, {r5-r11}
|
|
|
-+
|
|
|
-+ /* align the destination to a cache-line */
|
|
|
-+ rsb r3, r0, #0
|
|
|
-+ ands r3, r3, #0x1C
|
|
|
-+ beq congruent_aligned32
|
|
|
-+ cmp r3, r2
|
|
|
-+ andhi r3, r2, #0x1C
|
|
|
-+
|
|
|
-+ /* conditionnaly copies 0 to 7 words (length in r3) */
|
|
|
-+ movs r12, r3, lsl #28
|
|
|
-+ ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
|
|
|
-+ ldmmi r1!, {r8, r9} /* 8 bytes */
|
|
|
-+ stmcs r0!, {r4, r5, r6, r7}
|
|
|
-+ stmmi r0!, {r8, r9}
|
|
|
-+ tst r3, #0x4
|
|
|
-+ ldrne r10,[r1], #4 /* 4 bytes */
|
|
|
-+ strne r10,[r0], #4
|
|
|
-+ sub r2, r2, r3
|
|
|
-+
|
|
|
-+congruent_aligned32:
|
|
|
-+ /*
|
|
|
-+ * here source is aligned to 32 bytes.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+cached_aligned32:
|
|
|
-+ subs r2, r2, #32
|
|
|
-+ blo less_than_32_left
|
|
|
-+
|
|
|
-+ /*
|
|
|
-+ * We preload a cache-line up to 64 bytes ahead. On the 926, this will
|
|
|
-+ * stall only until the requested world is fetched, but the linefill
|
|
|
-+ * continues in the the background.
|
|
|
-+ * While the linefill is going, we write our previous cache-line
|
|
|
-+ * into the write-buffer (which should have some free space).
|
|
|
-+ * When the linefill is done, the writebuffer will
|
|
|
-+ * start dumping its content into memory
|
|
|
-+ *
|
|
|
-+ * While all this is going, we then load a full cache line into
|
|
|
-+ * 8 registers, this cache line should be in the cache by now
|
|
|
-+ * (or partly in the cache).
|
|
|
-+ *
|
|
|
-+ * This code should work well regardless of the source/dest alignment.
|
|
|
-+ *
|
|
|
-+ */
|
|
|
-+
|
|
|
-+ /* Align the preload register to a cache-line because the cpu does
|
|
|
-+ * "critical word first" (the first word requested is loaded first).
|
|
|
-+ */
|
|
|
-+ @ bic r12, r1, #0x1F
|
|
|
-+ @ add r12, r12, #64
|
|
|
-+
|
|
|
-+1: ldmia r1!, { r4-r11 }
|
|
|
-+ subs r2, r2, #32
|
|
|
-+
|
|
|
-+ /*
|
|
|
-+ * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
|
|
|
-+ * for ARM9 preload will not be safely guarded by the preceding subs.
|
|
|
-+ * When it is safely guarded the only possibility to have SIGSEGV here
|
|
|
-+ * is because the caller overstates the length.
|
|
|
-+ */
|
|
|
-+ @ ldrhi r3, [r12], #32 /* cheap ARM9 preload */
|
|
|
-+ stmia r0!, { r4-r11 }
|
|
|
-+ bhs 1b
|
|
|
-+
|
|
|
-+ add r2, r2, #32
|
|
|
-+
|
|
|
-+less_than_32_left:
|
|
|
-+ /*
|
|
|
-+ * less than 32 bytes left at this point (length in r2)
|
|
|
-+ */
|
|
|
-+
|
|
|
-+ /* skip all this if there is nothing to do, which should
|
|
|
-+ * be a common case (if not executed the code below takes
|
|
|
-+ * about 16 cycles)
|
|
|
-+ */
|
|
|
-+ tst r2, #0x1F
|
|
|
-+ beq 1f
|
|
|
-+
|
|
|
-+ /* conditionnaly copies 0 to 31 bytes */
|
|
|
-+ movs r12, r2, lsl #28
|
|
|
-+ ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
|
|
|
-+ ldmmi r1!, {r8, r9} /* 8 bytes */
|
|
|
-+ stmcs r0!, {r4, r5, r6, r7}
|
|
|
-+ stmmi r0!, {r8, r9}
|
|
|
-+ movs r12, r2, lsl #30
|
|
|
-+ ldrcs r3, [r1], #4 /* 4 bytes */
|
|
|
-+ ldrhmi r4, [r1], #2 /* 2 bytes */
|
|
|
-+ strcs r3, [r0], #4
|
|
|
-+ strhmi r4, [r0], #2
|
|
|
-+ tst r2, #0x1
|
|
|
-+ ldrbne r3, [r1] /* last byte */
|
|
|
-+ strbne r3, [r0]
|
|
|
-+
|
|
|
-+ /* we're done! restore everything and return */
|
|
|
-+1: ldmfd sp!, {r5-r11}
|
|
|
-+ ldmfd sp!, {r0, r4, lr}
|
|
|
-+ bx lr
|
|
|
-+
|
|
|
-+ /********************************************************************/
|
|
|
-+
|
|
|
-+non_congruent:
|
|
|
-+ /*
|
|
|
-+ * here source is aligned to 4 bytes
|
|
|
-+ * but destination is not.
|
|
|
-+ *
|
|
|
-+ * in the code below r2 is the number of bytes read
|
|
|
-+ * (the number of bytes written is always smaller, because we have
|
|
|
-+ * partial words in the shift queue)
|
|
|
-+ */
|
|
|
-+ cmp r2, #4
|
|
|
-+ blo copy_last_3_and_return
|
|
|
-+
|
|
|
-+ /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
|
|
|
-+ * frame. Don't update sp.
|
|
|
-+ */
|
|
|
-+ stmea sp, {r5-r11}
|
|
|
-+
|
|
|
-+ /* compute shifts needed to align src to dest */
|
|
|
-+ rsb r5, r0, #0
|
|
|
-+ and r5, r5, #3 /* r5 = # bytes in partial words */
|
|
|
-+ mov r12, r5, lsl #3 /* r12 = right */
|
|
|
-+ rsb lr, r12, #32 /* lr = left */
|
|
|
-+
|
|
|
-+ /* read the first word */
|
|
|
-+ ldr r3, [r1], #4
|
|
|
-+ sub r2, r2, #4
|
|
|
-+
|
|
|
-+ /* write a partial word (0 to 3 bytes), such that destination
|
|
|
-+ * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
|
|
|
-+ */
|
|
|
-+ movs r5, r5, lsl #31
|
|
|
-+ strbmi r3, [r0], #1
|
|
|
-+ movmi r3, r3, lsr #8
|
|
|
-+ strbcs r3, [r0], #1
|
|
|
-+ movcs r3, r3, lsr #8
|
|
|
-+ strbcs r3, [r0], #1
|
|
|
-+ movcs r3, r3, lsr #8
|
|
|
-+
|
|
|
-+ cmp r2, #4
|
|
|
-+ blo partial_word_tail
|
|
|
-+
|
|
|
-+ /* Align destination to 32 bytes (cache line boundary) */
|
|
|
-+1: tst r0, #0x1c
|
|
|
-+ beq 2f
|
|
|
-+ ldr r5, [r1], #4
|
|
|
-+ sub r2, r2, #4
|
|
|
-+ orr r4, r3, r5, lsl lr
|
|
|
-+ mov r3, r5, lsr r12
|
|
|
-+ str r4, [r0], #4
|
|
|
-+ cmp r2, #4
|
|
|
-+ bhs 1b
|
|
|
-+ blo partial_word_tail
|
|
|
-+
|
|
|
-+ /* copy 32 bytes at a time */
|
|
|
-+2: subs r2, r2, #32
|
|
|
-+ blo less_than_thirtytwo
|
|
|
-+
|
|
|
-+ /* Use immediate mode for the shifts, because there is an extra cycle
|
|
|
-+ * for register shifts, which could account for up to 50% of
|
|
|
-+ * performance hit.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+ cmp r12, #24
|
|
|
-+ beq loop24
|
|
|
-+ cmp r12, #8
|
|
|
-+ beq loop8
|
|
|
-+
|
|
|
-+loop16:
|
|
|
-+ ldr r12, [r1], #4
|
|
|
-+1: mov r4, r12
|
|
|
-+ ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
|
|
|
-+ subs r2, r2, #32
|
|
|
-+ ldrhs r12, [r1], #4
|
|
|
-+ orr r3, r3, r4, lsl #16
|
|
|
-+ mov r4, r4, lsr #16
|
|
|
-+ orr r4, r4, r5, lsl #16
|
|
|
-+ mov r5, r5, lsr #16
|
|
|
-+ orr r5, r5, r6, lsl #16
|
|
|
-+ mov r6, r6, lsr #16
|
|
|
-+ orr r6, r6, r7, lsl #16
|
|
|
-+ mov r7, r7, lsr #16
|
|
|
-+ orr r7, r7, r8, lsl #16
|
|
|
-+ mov r8, r8, lsr #16
|
|
|
-+ orr r8, r8, r9, lsl #16
|
|
|
-+ mov r9, r9, lsr #16
|
|
|
-+ orr r9, r9, r10, lsl #16
|
|
|
-+ mov r10, r10, lsr #16
|
|
|
-+ orr r10, r10, r11, lsl #16
|
|
|
-+ stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
|
|
|
-+ mov r3, r11, lsr #16
|
|
|
-+ bhs 1b
|
|
|
-+ b less_than_thirtytwo
|
|
|
-+
|
|
|
-+loop8:
|
|
|
-+ ldr r12, [r1], #4
|
|
|
-+1: mov r4, r12
|
|
|
-+ ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
|
|
|
-+ subs r2, r2, #32
|
|
|
-+ ldrhs r12, [r1], #4
|
|
|
-+ orr r3, r3, r4, lsl #24
|
|
|
-+ mov r4, r4, lsr #8
|
|
|
-+ orr r4, r4, r5, lsl #24
|
|
|
-+ mov r5, r5, lsr #8
|
|
|
-+ orr r5, r5, r6, lsl #24
|
|
|
-+ mov r6, r6, lsr #8
|
|
|
-+ orr r6, r6, r7, lsl #24
|
|
|
-+ mov r7, r7, lsr #8
|
|
|
-+ orr r7, r7, r8, lsl #24
|
|
|
-+ mov r8, r8, lsr #8
|
|
|
-+ orr r8, r8, r9, lsl #24
|
|
|
-+ mov r9, r9, lsr #8
|
|
|
-+ orr r9, r9, r10, lsl #24
|
|
|
-+ mov r10, r10, lsr #8
|
|
|
-+ orr r10, r10, r11, lsl #24
|
|
|
-+ stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
|
|
|
-+ mov r3, r11, lsr #8
|
|
|
-+ bhs 1b
|
|
|
-+ b less_than_thirtytwo
|
|
|
-+
|
|
|
-+loop24:
|
|
|
-+ ldr r12, [r1], #4
|
|
|
-+1: mov r4, r12
|
|
|
-+ ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
|
|
|
-+ subs r2, r2, #32
|
|
|
-+ ldrhs r12, [r1], #4
|
|
|
-+ orr r3, r3, r4, lsl #8
|
|
|
-+ mov r4, r4, lsr #24
|
|
|
-+ orr r4, r4, r5, lsl #8
|
|
|
-+ mov r5, r5, lsr #24
|
|
|
-+ orr r5, r5, r6, lsl #8
|
|
|
-+ mov r6, r6, lsr #24
|
|
|
-+ orr r6, r6, r7, lsl #8
|
|
|
-+ mov r7, r7, lsr #24
|
|
|
-+ orr r7, r7, r8, lsl #8
|
|
|
-+ mov r8, r8, lsr #24
|
|
|
-+ orr r8, r8, r9, lsl #8
|
|
|
-+ mov r9, r9, lsr #24
|
|
|
-+ orr r9, r9, r10, lsl #8
|
|
|
-+ mov r10, r10, lsr #24
|
|
|
-+ orr r10, r10, r11, lsl #8
|
|
|
-+ stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
|
|
|
-+ mov r3, r11, lsr #24
|
|
|
-+ bhs 1b
|
|
|
-+
|
|
|
-+less_than_thirtytwo:
|
|
|
-+ /* copy the last 0 to 31 bytes of the source */
|
|
|
-+ rsb r12, lr, #32 /* we corrupted r12, recompute it */
|
|
|
-+ add r2, r2, #32
|
|
|
-+ cmp r2, #4
|
|
|
-+ blo partial_word_tail
|
|
|
-+
|
|
|
-+1: ldr r5, [r1], #4
|
|
|
-+ sub r2, r2, #4
|
|
|
-+ orr r4, r3, r5, lsl lr
|
|
|
-+ mov r3, r5, lsr r12
|
|
|
-+ str r4, [r0], #4
|
|
|
-+ cmp r2, #4
|
|
|
-+ bhs 1b
|
|
|
-+
|
|
|
-+partial_word_tail:
|
|
|
-+ /* we have a partial word in the input buffer */
|
|
|
-+ movs r5, lr, lsl #(31-3)
|
|
|
-+ strbmi r3, [r0], #1
|
|
|
-+ movmi r3, r3, lsr #8
|
|
|
-+ strbcs r3, [r0], #1
|
|
|
-+ movcs r3, r3, lsr #8
|
|
|
-+ strbcs r3, [r0], #1
|
|
|
-+
|
|
|
-+ /* Refill spilled registers from the stack. Don't update sp. */
|
|
|
-+ ldmfd sp, {r5-r11}
|
|
|
-+
|
|
|
-+copy_last_3_and_return:
|
|
|
-+ movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
|
|
|
-+ ldrbmi r2, [r1], #1
|
|
|
-+ ldrbcs r3, [r1], #1
|
|
|
-+ ldrbcs r12,[r1]
|
|
|
-+ strbmi r2, [r0], #1
|
|
|
-+ strbcs r3, [r0], #1
|
|
|
-+ strbcs r12,[r0]
|
|
|
-+
|
|
|
-+ /* we're done! restore sp and spilled registers and return */
|
|
|
-+ add sp, sp, #28
|
|
|
-+ ldmfd sp!, {r0, r4, lr}
|
|
|
-+ bx lr
|
|
|
-+
|
|
|
-+#endif
|
|
|
---- a/src/string/armel/memcpy.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,381 +0,0 @@
|
|
|
--/*
|
|
|
-- * Copyright (C) 2008 The Android Open Source Project
|
|
|
-- * All rights reserved.
|
|
|
-- *
|
|
|
-- * Redistribution and use in source and binary forms, with or without
|
|
|
-- * modification, are permitted provided that the following conditions
|
|
|
-- * are met:
|
|
|
-- * * Redistributions of source code must retain the above copyright
|
|
|
-- * notice, this list of conditions and the following disclaimer.
|
|
|
-- * * Redistributions in binary form must reproduce the above copyright
|
|
|
-- * notice, this list of conditions and the following disclaimer in
|
|
|
-- * the documentation and/or other materials provided with the
|
|
|
-- * distribution.
|
|
|
-- *
|
|
|
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
-- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
-- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
-- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
-- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
-- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
-- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
|
-- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
|
-- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
|
-- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
|
-- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
-- * SUCH DAMAGE.
|
|
|
-- */
|
|
|
--
|
|
|
--
|
|
|
--/*
|
|
|
-- * Optimized memcpy() for ARM.
|
|
|
-- *
|
|
|
-- * note that memcpy() always returns the destination pointer,
|
|
|
-- * so we have to preserve R0.
|
|
|
-- */
|
|
|
--
|
|
|
--/*
|
|
|
-- * This file has been modified from the original for use in musl libc.
|
|
|
-- * The main changes are: addition of .type memcpy,%function to make the
|
|
|
-- * code safely callable from thumb mode, adjusting the return
|
|
|
-- * instructions to be compatible with pre-thumb ARM cpus, and removal
|
|
|
-- * of prefetch code that is not compatible with older cpus.
|
|
|
-- */
|
|
|
--
|
|
|
--.global memcpy
|
|
|
--.type memcpy,%function
|
|
|
--memcpy:
|
|
|
-- /* The stack must always be 64-bits aligned to be compliant with the
|
|
|
-- * ARM ABI. Since we have to save R0, we might as well save R4
|
|
|
-- * which we can use for better pipelining of the reads below
|
|
|
-- */
|
|
|
-- .fnstart
|
|
|
-- .save {r0, r4, lr}
|
|
|
-- stmfd sp!, {r0, r4, lr}
|
|
|
-- /* Making room for r5-r11 which will be spilled later */
|
|
|
-- .pad #28
|
|
|
-- sub sp, sp, #28
|
|
|
--
|
|
|
-- /* it simplifies things to take care of len<4 early */
|
|
|
-- cmp r2, #4
|
|
|
-- blo copy_last_3_and_return
|
|
|
--
|
|
|
-- /* compute the offset to align the source
|
|
|
-- * offset = (4-(src&3))&3 = -src & 3
|
|
|
-- */
|
|
|
-- rsb r3, r1, #0
|
|
|
-- ands r3, r3, #3
|
|
|
-- beq src_aligned
|
|
|
--
|
|
|
-- /* align source to 32 bits. We need to insert 2 instructions between
|
|
|
-- * a ldr[b|h] and str[b|h] because byte and half-word instructions
|
|
|
-- * stall 2 cycles.
|
|
|
-- */
|
|
|
-- movs r12, r3, lsl #31
|
|
|
-- sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */
|
|
|
-- .word 0x44d13001 /* ldrbmi r3, [r1], #1 */
|
|
|
-- .word 0x24d14001 /* ldrbcs r4, [r1], #1 */
|
|
|
-- .word 0x24d1c001 /* ldrbcs r12,[r1], #1 */
|
|
|
-- .word 0x44c03001 /* strbmi r3, [r0], #1 */
|
|
|
-- .word 0x24c04001 /* strbcs r4, [r0], #1 */
|
|
|
-- .word 0x24c0c001 /* strbcs r12,[r0], #1 */
|
|
|
--
|
|
|
--src_aligned:
|
|
|
--
|
|
|
-- /* see if src and dst are aligned together (congruent) */
|
|
|
-- eor r12, r0, r1
|
|
|
-- tst r12, #3
|
|
|
-- bne non_congruent
|
|
|
--
|
|
|
-- /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
|
|
|
-- * frame. Don't update sp.
|
|
|
-- */
|
|
|
-- stmea sp, {r5-r11}
|
|
|
--
|
|
|
-- /* align the destination to a cache-line */
|
|
|
-- rsb r3, r0, #0
|
|
|
-- ands r3, r3, #0x1C
|
|
|
-- beq congruent_aligned32
|
|
|
-- cmp r3, r2
|
|
|
-- andhi r3, r2, #0x1C
|
|
|
--
|
|
|
-- /* conditionnaly copies 0 to 7 words (length in r3) */
|
|
|
-- movs r12, r3, lsl #28
|
|
|
-- ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
|
|
|
-- ldmmi r1!, {r8, r9} /* 8 bytes */
|
|
|
-- stmcs r0!, {r4, r5, r6, r7}
|
|
|
-- stmmi r0!, {r8, r9}
|
|
|
-- tst r3, #0x4
|
|
|
-- ldrne r10,[r1], #4 /* 4 bytes */
|
|
|
-- strne r10,[r0], #4
|
|
|
-- sub r2, r2, r3
|
|
|
--
|
|
|
--congruent_aligned32:
|
|
|
-- /*
|
|
|
-- * here source is aligned to 32 bytes.
|
|
|
-- */
|
|
|
--
|
|
|
--cached_aligned32:
|
|
|
-- subs r2, r2, #32
|
|
|
-- blo less_than_32_left
|
|
|
--
|
|
|
-- /*
|
|
|
-- * We preload a cache-line up to 64 bytes ahead. On the 926, this will
|
|
|
-- * stall only until the requested world is fetched, but the linefill
|
|
|
-- * continues in the the background.
|
|
|
-- * While the linefill is going, we write our previous cache-line
|
|
|
-- * into the write-buffer (which should have some free space).
|
|
|
-- * When the linefill is done, the writebuffer will
|
|
|
-- * start dumping its content into memory
|
|
|
-- *
|
|
|
-- * While all this is going, we then load a full cache line into
|
|
|
-- * 8 registers, this cache line should be in the cache by now
|
|
|
-- * (or partly in the cache).
|
|
|
-- *
|
|
|
-- * This code should work well regardless of the source/dest alignment.
|
|
|
-- *
|
|
|
-- */
|
|
|
--
|
|
|
-- /* Align the preload register to a cache-line because the cpu does
|
|
|
-- * "critical word first" (the first word requested is loaded first).
|
|
|
-- */
|
|
|
-- @ bic r12, r1, #0x1F
|
|
|
-- @ add r12, r12, #64
|
|
|
--
|
|
|
--1: ldmia r1!, { r4-r11 }
|
|
|
-- subs r2, r2, #32
|
|
|
--
|
|
|
-- /*
|
|
|
-- * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
|
|
|
-- * for ARM9 preload will not be safely guarded by the preceding subs.
|
|
|
-- * When it is safely guarded the only possibility to have SIGSEGV here
|
|
|
-- * is because the caller overstates the length.
|
|
|
-- */
|
|
|
-- @ ldrhi r3, [r12], #32 /* cheap ARM9 preload */
|
|
|
-- stmia r0!, { r4-r11 }
|
|
|
-- bhs 1b
|
|
|
--
|
|
|
-- add r2, r2, #32
|
|
|
--
|
|
|
--less_than_32_left:
|
|
|
-- /*
|
|
|
-- * less than 32 bytes left at this point (length in r2)
|
|
|
-- */
|
|
|
--
|
|
|
-- /* skip all this if there is nothing to do, which should
|
|
|
-- * be a common case (if not executed the code below takes
|
|
|
-- * about 16 cycles)
|
|
|
-- */
|
|
|
-- tst r2, #0x1F
|
|
|
-- beq 1f
|
|
|
--
|
|
|
-- /* conditionnaly copies 0 to 31 bytes */
|
|
|
-- movs r12, r2, lsl #28
|
|
|
-- ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
|
|
|
-- ldmmi r1!, {r8, r9} /* 8 bytes */
|
|
|
-- stmcs r0!, {r4, r5, r6, r7}
|
|
|
-- stmmi r0!, {r8, r9}
|
|
|
-- movs r12, r2, lsl #30
|
|
|
-- ldrcs r3, [r1], #4 /* 4 bytes */
|
|
|
-- .word 0x40d140b2 /* ldrhmi r4, [r1], #2 */ /* 2 bytes */
|
|
|
-- strcs r3, [r0], #4
|
|
|
-- .word 0x40c040b2 /* strhmi r4, [r0], #2 */
|
|
|
-- tst r2, #0x1
|
|
|
-- .word 0x15d13000 /* ldrbne r3, [r1] */ /* last byte */
|
|
|
-- .word 0x15c03000 /* strbne r3, [r0] */
|
|
|
--
|
|
|
-- /* we're done! restore everything and return */
|
|
|
--1: ldmfd sp!, {r5-r11}
|
|
|
-- ldmfd sp!, {r0, r4, lr}
|
|
|
-- tst lr, #1
|
|
|
-- moveq pc, lr
|
|
|
-- bx lr
|
|
|
--
|
|
|
-- /********************************************************************/
|
|
|
--
|
|
|
--non_congruent:
|
|
|
-- /*
|
|
|
-- * here source is aligned to 4 bytes
|
|
|
-- * but destination is not.
|
|
|
-- *
|
|
|
-- * in the code below r2 is the number of bytes read
|
|
|
-- * (the number of bytes written is always smaller, because we have
|
|
|
-- * partial words in the shift queue)
|
|
|
-- */
|
|
|
-- cmp r2, #4
|
|
|
-- blo copy_last_3_and_return
|
|
|
--
|
|
|
-- /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
|
|
|
-- * frame. Don't update sp.
|
|
|
-- */
|
|
|
-- stmea sp, {r5-r11}
|
|
|
--
|
|
|
-- /* compute shifts needed to align src to dest */
|
|
|
-- rsb r5, r0, #0
|
|
|
-- and r5, r5, #3 /* r5 = # bytes in partial words */
|
|
|
-- mov r12, r5, lsl #3 /* r12 = right */
|
|
|
-- rsb lr, r12, #32 /* lr = left */
|
|
|
--
|
|
|
-- /* read the first word */
|
|
|
-- ldr r3, [r1], #4
|
|
|
-- sub r2, r2, #4
|
|
|
--
|
|
|
-- /* write a partial word (0 to 3 bytes), such that destination
|
|
|
-- * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
|
|
|
-- */
|
|
|
-- movs r5, r5, lsl #31
|
|
|
-- .word 0x44c03001 /* strbmi r3, [r0], #1 */
|
|
|
-- movmi r3, r3, lsr #8
|
|
|
-- .word 0x24c03001 /* strbcs r3, [r0], #1 */
|
|
|
-- movcs r3, r3, lsr #8
|
|
|
-- .word 0x24c03001 /* strbcs r3, [r0], #1 */
|
|
|
-- movcs r3, r3, lsr #8
|
|
|
--
|
|
|
-- cmp r2, #4
|
|
|
-- blo partial_word_tail
|
|
|
--
|
|
|
-- /* Align destination to 32 bytes (cache line boundary) */
|
|
|
--1: tst r0, #0x1c
|
|
|
-- beq 2f
|
|
|
-- ldr r5, [r1], #4
|
|
|
-- sub r2, r2, #4
|
|
|
-- orr r4, r3, r5, lsl lr
|
|
|
-- mov r3, r5, lsr r12
|
|
|
-- str r4, [r0], #4
|
|
|
-- cmp r2, #4
|
|
|
-- bhs 1b
|
|
|
-- blo partial_word_tail
|
|
|
--
|
|
|
-- /* copy 32 bytes at a time */
|
|
|
--2: subs r2, r2, #32
|
|
|
-- blo less_than_thirtytwo
|
|
|
--
|
|
|
-- /* Use immediate mode for the shifts, because there is an extra cycle
|
|
|
-- * for register shifts, which could account for up to 50% of
|
|
|
-- * performance hit.
|
|
|
-- */
|
|
|
--
|
|
|
-- cmp r12, #24
|
|
|
-- beq loop24
|
|
|
-- cmp r12, #8
|
|
|
-- beq loop8
|
|
|
--
|
|
|
--loop16:
|
|
|
-- ldr r12, [r1], #4
|
|
|
--1: mov r4, r12
|
|
|
-- ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
|
|
|
-- subs r2, r2, #32
|
|
|
-- ldrhs r12, [r1], #4
|
|
|
-- orr r3, r3, r4, lsl #16
|
|
|
-- mov r4, r4, lsr #16
|
|
|
-- orr r4, r4, r5, lsl #16
|
|
|
-- mov r5, r5, lsr #16
|
|
|
-- orr r5, r5, r6, lsl #16
|
|
|
-- mov r6, r6, lsr #16
|
|
|
-- orr r6, r6, r7, lsl #16
|
|
|
-- mov r7, r7, lsr #16
|
|
|
-- orr r7, r7, r8, lsl #16
|
|
|
-- mov r8, r8, lsr #16
|
|
|
-- orr r8, r8, r9, lsl #16
|
|
|
-- mov r9, r9, lsr #16
|
|
|
-- orr r9, r9, r10, lsl #16
|
|
|
-- mov r10, r10, lsr #16
|
|
|
-- orr r10, r10, r11, lsl #16
|
|
|
-- stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
|
|
|
-- mov r3, r11, lsr #16
|
|
|
-- bhs 1b
|
|
|
-- b less_than_thirtytwo
|
|
|
--
|
|
|
--loop8:
|
|
|
-- ldr r12, [r1], #4
|
|
|
--1: mov r4, r12
|
|
|
-- ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
|
|
|
-- subs r2, r2, #32
|
|
|
-- ldrhs r12, [r1], #4
|
|
|
-- orr r3, r3, r4, lsl #24
|
|
|
-- mov r4, r4, lsr #8
|
|
|
-- orr r4, r4, r5, lsl #24
|
|
|
-- mov r5, r5, lsr #8
|
|
|
-- orr r5, r5, r6, lsl #24
|
|
|
-- mov r6, r6, lsr #8
|
|
|
-- orr r6, r6, r7, lsl #24
|
|
|
-- mov r7, r7, lsr #8
|
|
|
-- orr r7, r7, r8, lsl #24
|
|
|
-- mov r8, r8, lsr #8
|
|
|
-- orr r8, r8, r9, lsl #24
|
|
|
-- mov r9, r9, lsr #8
|
|
|
-- orr r9, r9, r10, lsl #24
|
|
|
-- mov r10, r10, lsr #8
|
|
|
-- orr r10, r10, r11, lsl #24
|
|
|
-- stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
|
|
|
-- mov r3, r11, lsr #8
|
|
|
-- bhs 1b
|
|
|
-- b less_than_thirtytwo
|
|
|
--
|
|
|
--loop24:
|
|
|
-- ldr r12, [r1], #4
|
|
|
--1: mov r4, r12
|
|
|
-- ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
|
|
|
-- subs r2, r2, #32
|
|
|
-- ldrhs r12, [r1], #4
|
|
|
-- orr r3, r3, r4, lsl #8
|
|
|
-- mov r4, r4, lsr #24
|
|
|
-- orr r4, r4, r5, lsl #8
|
|
|
-- mov r5, r5, lsr #24
|
|
|
-- orr r5, r5, r6, lsl #8
|
|
|
-- mov r6, r6, lsr #24
|
|
|
-- orr r6, r6, r7, lsl #8
|
|
|
-- mov r7, r7, lsr #24
|
|
|
-- orr r7, r7, r8, lsl #8
|
|
|
-- mov r8, r8, lsr #24
|
|
|
-- orr r8, r8, r9, lsl #8
|
|
|
-- mov r9, r9, lsr #24
|
|
|
-- orr r9, r9, r10, lsl #8
|
|
|
-- mov r10, r10, lsr #24
|
|
|
-- orr r10, r10, r11, lsl #8
|
|
|
-- stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
|
|
|
-- mov r3, r11, lsr #24
|
|
|
-- bhs 1b
|
|
|
--
|
|
|
--less_than_thirtytwo:
|
|
|
-- /* copy the last 0 to 31 bytes of the source */
|
|
|
-- rsb r12, lr, #32 /* we corrupted r12, recompute it */
|
|
|
-- add r2, r2, #32
|
|
|
-- cmp r2, #4
|
|
|
-- blo partial_word_tail
|
|
|
--
|
|
|
--1: ldr r5, [r1], #4
|
|
|
-- sub r2, r2, #4
|
|
|
-- orr r4, r3, r5, lsl lr
|
|
|
-- mov r3, r5, lsr r12
|
|
|
-- str r4, [r0], #4
|
|
|
-- cmp r2, #4
|
|
|
-- bhs 1b
|
|
|
--
|
|
|
--partial_word_tail:
|
|
|
-- /* we have a partial word in the input buffer */
|
|
|
-- movs r5, lr, lsl #(31-3)
|
|
|
-- .word 0x44c03001 /* strbmi r3, [r0], #1 */
|
|
|
-- movmi r3, r3, lsr #8
|
|
|
-- .word 0x24c03001 /* strbcs r3, [r0], #1 */
|
|
|
-- movcs r3, r3, lsr #8
|
|
|
-- .word 0x24c03001 /* strbcs r3, [r0], #1 */
|
|
|
--
|
|
|
-- /* Refill spilled registers from the stack. Don't update sp. */
|
|
|
-- ldmfd sp, {r5-r11}
|
|
|
--
|
|
|
--copy_last_3_and_return:
|
|
|
-- movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
|
|
|
-- .word 0x44d12001 /* ldrbmi r2, [r1], #1 */
|
|
|
-- .word 0x24d13001 /* ldrbcs r3, [r1], #1 */
|
|
|
-- .word 0x25d1c000 /* ldrbcs r12,[r1] */
|
|
|
-- .word 0x44c02001 /* strbmi r2, [r0], #1 */
|
|
|
-- .word 0x24c03001 /* strbcs r3, [r0], #1 */
|
|
|
-- .word 0x25c0c000 /* strbcs r12,[r0] */
|
|
|
--
|
|
|
-- /* we're done! restore sp and spilled registers and return */
|
|
|
-- add sp, sp, #28
|
|
|
-- ldmfd sp!, {r0, r4, lr}
|
|
|
-- tst lr, #1
|
|
|
-- moveq pc, lr
|
|
|
-- bx lr
|
|
|
---- a/src/string/armel/memcpy.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--memcpy.s
|
|
|
---- a/src/string/armhf/memcpy.sub
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--../armel/memcpy.s
|
|
|
---- a/src/thread/__syscall_cp.c
|
|
|
-+++ b/src/thread/__syscall_cp.c
|
|
|
-@@ -1,9 +1,7 @@
|
|
|
- #include "pthread_impl.h"
|
|
|
- #include "syscall.h"
|
|
|
-
|
|
|
--#ifdef SHARED
|
|
|
- __attribute__((__visibility__("hidden")))
|
|
|
--#endif
|
|
|
- long __syscall_cp_c();
|
|
|
-
|
|
|
- static long sccp(syscall_arg_t nr,
|
|
|
---- a/src/thread/__tls_get_addr.c
|
|
|
-+++ b/src/thread/__tls_get_addr.c
|
|
|
-@@ -1,16 +1,16 @@
|
|
|
- #include <stddef.h>
|
|
|
- #include "pthread_impl.h"
|
|
|
-+#include "libc.h"
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+void *__tls_get_new(size_t *);
|
|
|
-
|
|
|
- void *__tls_get_addr(size_t *v)
|
|
|
- {
|
|
|
- pthread_t self = __pthread_self();
|
|
|
--#ifdef SHARED
|
|
|
-- __attribute__((__visibility__("hidden")))
|
|
|
-- void *__tls_get_new(size_t *);
|
|
|
- if (v[0]<=(size_t)self->dtv[0])
|
|
|
- return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
|
|
|
- return __tls_get_new(v);
|
|
|
--#else
|
|
|
-- return (char *)self->dtv[1]+v[1]+DTP_OFFSET;
|
|
|
--#endif
|
|
|
- }
|
|
|
-+
|
|
|
-+weak_alias(__tls_get_addr, __tls_get_new);
|
|
|
---- a/src/thread/aarch64/syscall_cp.s
|
|
|
-+++ b/src/thread/aarch64/syscall_cp.s
|
|
|
-@@ -17,7 +17,7 @@
|
|
|
- __syscall_cp_asm:
|
|
|
- __cp_begin:
|
|
|
- ldr w0,[x0]
|
|
|
-- cbnz w0,1f
|
|
|
-+ cbnz w0,__cp_cancel
|
|
|
- mov x8,x1
|
|
|
- mov x0,x2
|
|
|
- mov x1,x3
|
|
|
-@@ -28,6 +28,5 @@ __cp_begin:
|
|
|
- svc 0
|
|
|
- __cp_end:
|
|
|
- ret
|
|
|
--
|
|
|
-- // cbnz might not be able to jump far enough
|
|
|
--1: b __cancel
|
|
|
-+__cp_cancel:
|
|
|
-+ b __cancel
|
|
|
---- /dev/null
|
|
|
-+++ b/src/thread/arm/__set_thread_area.c
|
|
|
-@@ -0,0 +1,49 @@
|
|
|
-+#include <stdint.h>
|
|
|
-+#include <elf.h>
|
|
|
-+#include "pthread_impl.h"
|
|
|
-+#include "libc.h"
|
|
|
-+
|
|
|
-+#define HWCAP_TLS (1 << 15)
|
|
|
-+
|
|
|
-+extern const unsigned char __attribute__((__visibility__("hidden")))
|
|
|
-+ __a_barrier_dummy[], __a_barrier_oldkuser[],
|
|
|
-+ __a_barrier_v6[], __a_barrier_v7[],
|
|
|
-+ __a_cas_dummy[], __a_cas_v6[], __a_cas_v7[],
|
|
|
-+ __a_gettp_dummy[];
|
|
|
-+
|
|
|
-+#define __a_barrier_kuser 0xffff0fa0
|
|
|
-+#define __a_cas_kuser 0xffff0fc0
|
|
|
-+#define __a_gettp_kuser 0xffff0fe0
|
|
|
-+
|
|
|
-+extern uintptr_t __attribute__((__visibility__("hidden")))
|
|
|
-+ __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr;
|
|
|
-+
|
|
|
-+#define SET(op,ver) (__a_##op##_ptr = \
|
|
|
-+ (uintptr_t)__a_##op##_##ver - (uintptr_t)__a_##op##_dummy)
|
|
|
-+
|
|
|
-+int __set_thread_area(void *p)
|
|
|
-+{
|
|
|
-+#if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7
|
|
|
-+ if (__hwcap & HWCAP_TLS) {
|
|
|
-+ size_t *aux;
|
|
|
-+ SET(cas, v7);
|
|
|
-+ SET(barrier, v7);
|
|
|
-+ for (aux=libc.auxv; *aux; aux+=2) {
|
|
|
-+ if (*aux != AT_PLATFORM) continue;
|
|
|
-+ const char *s = (void *)aux[1];
|
|
|
-+ if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break;
|
|
|
-+ SET(cas, v6);
|
|
|
-+ SET(barrier, v6);
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
-+ } else {
|
|
|
-+ int ver = *(int *)0xffff0ffc;
|
|
|
-+ SET(gettp, kuser);
|
|
|
-+ SET(cas, kuser);
|
|
|
-+ SET(barrier, kuser);
|
|
|
-+ if (ver < 2) a_crash();
|
|
|
-+ if (ver < 3) SET(barrier, oldkuser);
|
|
|
-+ }
|
|
|
-+#endif
|
|
|
-+ return __syscall(0xf0005, p);
|
|
|
-+}
|
|
|
---- a/src/thread/arm/__set_thread_area.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1 +0,0 @@
|
|
|
--/* Replaced by C code in arch/arm/src */
|
|
|
---- a/src/thread/arm/__unmapself.s
|
|
|
-+++ b/src/thread/arm/__unmapself.s
|
|
|
-@@ -1,3 +1,4 @@
|
|
|
-+.syntax unified
|
|
|
- .text
|
|
|
- .global __unmapself
|
|
|
- .type __unmapself,%function
|
|
|
---- /dev/null
|
|
|
-+++ b/src/thread/arm/atomics.s
|
|
|
-@@ -0,0 +1,113 @@
|
|
|
-+.syntax unified
|
|
|
-+.text
|
|
|
-+
|
|
|
-+.global __a_barrier
|
|
|
-+.hidden __a_barrier
|
|
|
-+.type __a_barrier,%function
|
|
|
-+__a_barrier:
|
|
|
-+ ldr ip,1f
|
|
|
-+ ldr ip,[pc,ip]
|
|
|
-+ add pc,pc,ip
|
|
|
-+1: .word __a_barrier_ptr-1b
|
|
|
-+.global __a_barrier_dummy
|
|
|
-+.hidden __a_barrier_dummy
|
|
|
-+__a_barrier_dummy:
|
|
|
-+ bx lr
|
|
|
-+.global __a_barrier_oldkuser
|
|
|
-+.hidden __a_barrier_oldkuser
|
|
|
-+__a_barrier_oldkuser:
|
|
|
-+ push {r0,r1,r2,r3,ip,lr}
|
|
|
-+ mov r1,r0
|
|
|
-+ mov r2,sp
|
|
|
-+ ldr ip,=0xffff0fc0
|
|
|
-+ mov lr,pc
|
|
|
-+ mov pc,ip
|
|
|
-+ pop {r0,r1,r2,r3,ip,lr}
|
|
|
-+ bx lr
|
|
|
-+.global __a_barrier_v6
|
|
|
-+.hidden __a_barrier_v6
|
|
|
-+__a_barrier_v6:
|
|
|
-+ mcr p15,0,r0,c7,c10,5
|
|
|
-+ bx lr
|
|
|
-+.global __a_barrier_v7
|
|
|
-+.hidden __a_barrier_v7
|
|
|
-+__a_barrier_v7:
|
|
|
-+ .word 0xf57ff05b /* dmb ish */
|
|
|
-+ bx lr
|
|
|
-+
|
|
|
-+.global __a_cas
|
|
|
-+.hidden __a_cas
|
|
|
-+.type __a_cas,%function
|
|
|
-+__a_cas:
|
|
|
-+ ldr ip,1f
|
|
|
-+ ldr ip,[pc,ip]
|
|
|
-+ add pc,pc,ip
|
|
|
-+1: .word __a_cas_ptr-1b
|
|
|
-+.global __a_cas_dummy
|
|
|
-+.hidden __a_cas_dummy
|
|
|
-+__a_cas_dummy:
|
|
|
-+ mov r3,r0
|
|
|
-+ ldr r0,[r2]
|
|
|
-+ subs r0,r3,r0
|
|
|
-+ streq r1,[r2]
|
|
|
-+ bx lr
|
|
|
-+.global __a_cas_v6
|
|
|
-+.hidden __a_cas_v6
|
|
|
-+__a_cas_v6:
|
|
|
-+ mov r3,r0
|
|
|
-+ mcr p15,0,r0,c7,c10,5
|
|
|
-+1: .word 0xe1920f9f /* ldrex r0,[r2] */
|
|
|
-+ subs r0,r3,r0
|
|
|
-+ .word 0x01820f91 /* strexeq r0,r1,[r2] */
|
|
|
-+ teqeq r0,#1
|
|
|
-+ beq 1b
|
|
|
-+ mcr p15,0,r0,c7,c10,5
|
|
|
-+ bx lr
|
|
|
-+.global __a_cas_v7
|
|
|
-+.hidden __a_cas_v7
|
|
|
-+__a_cas_v7:
|
|
|
-+ mov r3,r0
|
|
|
-+ .word 0xf57ff05b /* dmb ish */
|
|
|
-+1: .word 0xe1920f9f /* ldrex r0,[r2] */
|
|
|
-+ subs r0,r3,r0
|
|
|
-+ .word 0x01820f91 /* strexeq r0,r1,[r2] */
|
|
|
-+ teqeq r0,#1
|
|
|
-+ beq 1b
|
|
|
-+ .word 0xf57ff05b /* dmb ish */
|
|
|
-+ bx lr
|
|
|
-+
|
|
|
-+.global __aeabi_read_tp
|
|
|
-+.type __aeabi_read_tp,%function
|
|
|
-+__aeabi_read_tp:
|
|
|
-+
|
|
|
-+.global __a_gettp
|
|
|
-+.hidden __a_gettp
|
|
|
-+.type __a_gettp,%function
|
|
|
-+__a_gettp:
|
|
|
-+ ldr r0,1f
|
|
|
-+ ldr r0,[pc,r0]
|
|
|
-+ add pc,pc,r0
|
|
|
-+1: .word __a_gettp_ptr-1b
|
|
|
-+.global __a_gettp_dummy
|
|
|
-+.hidden __a_gettp_dummy
|
|
|
-+__a_gettp_dummy:
|
|
|
-+ mrc p15,0,r0,c13,c0,3
|
|
|
-+ bx lr
|
|
|
-+
|
|
|
-+.data
|
|
|
-+.align 2
|
|
|
-+
|
|
|
-+.global __a_barrier_ptr
|
|
|
-+.hidden __a_barrier_ptr
|
|
|
-+__a_barrier_ptr:
|
|
|
-+ .word 0
|
|
|
-+
|
|
|
-+.global __a_cas_ptr
|
|
|
-+.hidden __a_cas_ptr
|
|
|
-+__a_cas_ptr:
|
|
|
-+ .word 0
|
|
|
-+
|
|
|
-+.global __a_gettp_ptr
|
|
|
-+.hidden __a_gettp_ptr
|
|
|
-+__a_gettp_ptr:
|
|
|
-+ .word 0
|
|
|
---- a/src/thread/arm/clone.s
|
|
|
-+++ b/src/thread/arm/clone.s
|
|
|
-@@ -1,3 +1,4 @@
|
|
|
-+.syntax unified
|
|
|
- .text
|
|
|
- .global __clone
|
|
|
- .type __clone,%function
|
|
|
-@@ -15,8 +16,6 @@ __clone:
|
|
|
- tst r0,r0
|
|
|
- beq 1f
|
|
|
- ldmfd sp!,{r4,r5,r6,r7}
|
|
|
-- tst lr,#1
|
|
|
-- moveq pc,lr
|
|
|
- bx lr
|
|
|
-
|
|
|
- 1: mov r0,r6
|
|
|
---- a/src/thread/arm/syscall_cp.s
|
|
|
-+++ b/src/thread/arm/syscall_cp.s
|
|
|
-@@ -1,3 +1,4 @@
|
|
|
-+.syntax unified
|
|
|
- .global __cp_begin
|
|
|
- .hidden __cp_begin
|
|
|
- .global __cp_end
|
|
|
-@@ -22,8 +23,6 @@ __cp_begin:
|
|
|
- svc 0
|
|
|
- __cp_end:
|
|
|
- ldmfd sp!,{r4,r5,r6,r7,lr}
|
|
|
-- tst lr,#1
|
|
|
-- moveq pc,lr
|
|
|
- bx lr
|
|
|
- __cp_cancel:
|
|
|
- ldmfd sp!,{r4,r5,r6,r7,lr}
|
|
|
---- a/src/thread/microblaze/syscall_cp.s
|
|
|
-+++ b/src/thread/microblaze/syscall_cp.s
|
|
|
-@@ -11,7 +11,7 @@
|
|
|
- __syscall_cp_asm:
|
|
|
- __cp_begin:
|
|
|
- lwi r5, r5, 0
|
|
|
-- bnei r5, __cancel
|
|
|
-+ bnei r5, __cp_cancel
|
|
|
- addi r12, r6, 0
|
|
|
- add r5, r7, r0
|
|
|
- add r6, r8, r0
|
|
|
-@@ -23,3 +23,5 @@ __cp_begin:
|
|
|
- __cp_end:
|
|
|
- rtsd r15, 8
|
|
|
- nop
|
|
|
-+__cp_cancel:
|
|
|
-+ bri __cancel
|
|
|
---- a/src/thread/or1k/syscall_cp.s
|
|
|
-+++ b/src/thread/or1k/syscall_cp.s
|
|
|
-@@ -12,7 +12,7 @@ __syscall_cp_asm:
|
|
|
- __cp_begin:
|
|
|
- l.lwz r3, 0(r3)
|
|
|
- l.sfeqi r3, 0
|
|
|
-- l.bnf __cancel
|
|
|
-+ l.bnf __cp_cancel
|
|
|
- l.ori r11, r4, 0
|
|
|
- l.ori r3, r5, 0
|
|
|
- l.ori r4, r6, 0
|
|
|
-@@ -24,3 +24,6 @@ __cp_begin:
|
|
|
- __cp_end:
|
|
|
- l.jr r9
|
|
|
- l.nop
|
|
|
-+__cp_cancel:
|
|
|
-+ l.j __cancel
|
|
|
-+ l.nop
|
|
|
---- a/src/thread/powerpc/syscall_cp.s
|
|
|
-+++ b/src/thread/powerpc/syscall_cp.s
|
|
|
-@@ -38,7 +38,7 @@ __cp_begin:
|
|
|
- cmpwi cr7, 0, 0 #compare r0 with 0, store result in cr7.
|
|
|
- beq+ cr7, 1f #jump to label 1 if r0 was 0
|
|
|
-
|
|
|
-- b __cancel #else call cancel
|
|
|
-+ b __cp_cancel #else call cancel
|
|
|
- 1:
|
|
|
- #ok, the cancel flag was not set
|
|
|
- # syscall: number goes to r0, the rest 3-8
|
|
|
-@@ -55,3 +55,5 @@ __cp_end:
|
|
|
- #else negate result.
|
|
|
- neg 3, 3
|
|
|
- blr
|
|
|
-+__cp_cancel:
|
|
|
-+ b __cancel
|
|
|
---- a/src/thread/pthread_cancel.c
|
|
|
-+++ b/src/thread/pthread_cancel.c
|
|
|
-@@ -1,12 +1,11 @@
|
|
|
-+#define _GNU_SOURCE
|
|
|
- #include <string.h>
|
|
|
- #include "pthread_impl.h"
|
|
|
- #include "syscall.h"
|
|
|
- #include "libc.h"
|
|
|
-
|
|
|
--#ifdef SHARED
|
|
|
- __attribute__((__visibility__("hidden")))
|
|
|
--#endif
|
|
|
--long __cancel(), __cp_cancel(), __syscall_cp_asm(), __syscall_cp_c();
|
|
|
-+long __cancel(), __syscall_cp_asm(), __syscall_cp_c();
|
|
|
-
|
|
|
- long __cancel()
|
|
|
- {
|
|
|
-@@ -17,12 +16,6 @@ long __cancel()
|
|
|
- return -ECANCELED;
|
|
|
- }
|
|
|
-
|
|
|
--/* If __syscall_cp_asm has adjusted the stack pointer, it must provide a
|
|
|
-- * definition of __cp_cancel to undo those adjustments and call __cancel.
|
|
|
-- * Otherwise, __cancel provides a definition for __cp_cancel. */
|
|
|
--
|
|
|
--weak_alias(__cancel, __cp_cancel);
|
|
|
--
|
|
|
- long __syscall_cp_asm(volatile void *, syscall_arg_t,
|
|
|
- syscall_arg_t, syscall_arg_t, syscall_arg_t,
|
|
|
- syscall_arg_t, syscall_arg_t, syscall_arg_t);
|
|
|
-@@ -52,24 +45,22 @@ static void _sigaddset(sigset_t *set, in
|
|
|
- set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1);
|
|
|
- }
|
|
|
-
|
|
|
--#ifdef SHARED
|
|
|
- __attribute__((__visibility__("hidden")))
|
|
|
--#endif
|
|
|
--extern const char __cp_begin[1], __cp_end[1];
|
|
|
-+extern const char __cp_begin[1], __cp_end[1], __cp_cancel[1];
|
|
|
-
|
|
|
- static void cancel_handler(int sig, siginfo_t *si, void *ctx)
|
|
|
- {
|
|
|
- pthread_t self = __pthread_self();
|
|
|
- ucontext_t *uc = ctx;
|
|
|
-- const char *ip = ((char **)&uc->uc_mcontext)[CANCEL_REG_IP];
|
|
|
-+ uintptr_t pc = uc->uc_mcontext.MC_PC;
|
|
|
-
|
|
|
- a_barrier();
|
|
|
- if (!self->cancel || self->canceldisable == PTHREAD_CANCEL_DISABLE) return;
|
|
|
-
|
|
|
- _sigaddset(&uc->uc_sigmask, SIGCANCEL);
|
|
|
-
|
|
|
-- if (self->cancelasync || ip >= __cp_begin && ip < __cp_end) {
|
|
|
-- ((char **)&uc->uc_mcontext)[CANCEL_REG_IP] = (char *)__cp_cancel;
|
|
|
-+ if (self->cancelasync || pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) {
|
|
|
-+ uc->uc_mcontext.MC_PC = (uintptr_t)__cp_cancel;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
---- /dev/null
|
|
|
-+++ b/src/thread/sh/__set_thread_area.c
|
|
|
-@@ -0,0 +1,40 @@
|
|
|
-+#include "pthread_impl.h"
|
|
|
-+#include "libc.h"
|
|
|
-+#include <elf.h>
|
|
|
-+
|
|
|
-+/* Also perform sh-specific init */
|
|
|
-+
|
|
|
-+#define CPU_HAS_LLSC 0x0040
|
|
|
-+#define CPU_HAS_CAS_L 0x0400
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+extern const char __sh_cas_gusa[], __sh_cas_llsc[], __sh_cas_imask[], __sh_cas_cas_l[];
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+const void *__sh_cas_ptr;
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+unsigned __sh_nommu;
|
|
|
-+
|
|
|
-+int __set_thread_area(void *p)
|
|
|
-+{
|
|
|
-+ size_t *aux;
|
|
|
-+ __asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
|
|
|
-+#ifndef __SH4A__
|
|
|
-+ __sh_cas_ptr = __sh_cas_gusa;
|
|
|
-+#if !defined(__SH3__) && !defined(__SH4__)
|
|
|
-+ for (aux=libc.auxv; *aux; aux+=2) {
|
|
|
-+ if (*aux != AT_PLATFORM) continue;
|
|
|
-+ const char *s = (void *)aux[1];
|
|
|
-+ if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
|
|
|
-+ __sh_cas_ptr = __sh_cas_imask;
|
|
|
-+ __sh_nommu = 1;
|
|
|
-+ }
|
|
|
-+#endif
|
|
|
-+ if (__hwcap & CPU_HAS_CAS_L)
|
|
|
-+ __sh_cas_ptr = __sh_cas_cas_l;
|
|
|
-+ else if (__hwcap & CPU_HAS_LLSC)
|
|
|
-+ __sh_cas_ptr = __sh_cas_llsc;
|
|
|
-+#endif
|
|
|
-+ return 0;
|
|
|
-+}
|
|
|
---- /dev/null
|
|
|
-+++ b/src/thread/sh/__unmapself.c
|
|
|
-@@ -0,0 +1,24 @@
|
|
|
-+#include "pthread_impl.h"
|
|
|
-+
|
|
|
-+void __unmapself_sh_mmu(void *, size_t);
|
|
|
-+void __unmapself_sh_nommu(void *, size_t);
|
|
|
-+
|
|
|
-+#if !defined(__SH3__) && !defined(__SH4__)
|
|
|
-+#define __unmapself __unmapself_sh_nommu
|
|
|
-+#include "dynlink.h"
|
|
|
-+#undef CRTJMP
|
|
|
-+#define CRTJMP(pc,sp) __asm__ __volatile__( \
|
|
|
-+ "mov.l @%0+,r0 ; mov.l @%0,r12 ; jmp @r0 ; mov %1,r15" \
|
|
|
-+ : : "r"(pc), "r"(sp) : "r0", "memory" )
|
|
|
-+#include "../__unmapself.c"
|
|
|
-+#undef __unmapself
|
|
|
-+extern __attribute__((__visibility__("hidden"))) unsigned __sh_nommu;
|
|
|
-+#else
|
|
|
-+#define __sh_nommu 0
|
|
|
-+#endif
|
|
|
-+
|
|
|
-+void __unmapself(void *base, size_t size)
|
|
|
-+{
|
|
|
-+ if (__sh_nommu) __unmapself_sh_nommu(base, size);
|
|
|
-+ else __unmapself_sh_mmu(base, size);
|
|
|
-+}
|
|
|
---- a/src/thread/sh/__unmapself.s
|
|
|
-+++ /dev/null
|
|
|
-@@ -1,22 +0,0 @@
|
|
|
--.text
|
|
|
--.global __unmapself_sh_mmu
|
|
|
--.type __unmapself_sh_mmu, @function
|
|
|
--__unmapself_sh_mmu:
|
|
|
-- mov #91, r3 ! SYS_munmap
|
|
|
-- trapa #31
|
|
|
--
|
|
|
-- or r0, r0
|
|
|
-- or r0, r0
|
|
|
-- or r0, r0
|
|
|
-- or r0, r0
|
|
|
-- or r0, r0
|
|
|
--
|
|
|
-- mov #1, r3 ! SYS_exit
|
|
|
-- mov #0, r4
|
|
|
-- trapa #31
|
|
|
--
|
|
|
-- or r0, r0
|
|
|
-- or r0, r0
|
|
|
-- or r0, r0
|
|
|
-- or r0, r0
|
|
|
-- or r0, r0
|
|
|
---- /dev/null
|
|
|
-+++ b/src/thread/sh/__unmapself_mmu.s
|
|
|
-@@ -0,0 +1,22 @@
|
|
|
-+.text
|
|
|
-+.global __unmapself_sh_mmu
|
|
|
-+.type __unmapself_sh_mmu, @function
|
|
|
-+__unmapself_sh_mmu:
|
|
|
-+ mov #91, r3 ! SYS_munmap
|
|
|
-+ trapa #31
|
|
|
-+
|
|
|
-+ or r0, r0
|
|
|
-+ or r0, r0
|
|
|
-+ or r0, r0
|
|
|
-+ or r0, r0
|
|
|
-+ or r0, r0
|
|
|
-+
|
|
|
-+ mov #1, r3 ! SYS_exit
|
|
|
-+ mov #0, r4
|
|
|
-+ trapa #31
|
|
|
-+
|
|
|
-+ or r0, r0
|
|
|
-+ or r0, r0
|
|
|
-+ or r0, r0
|
|
|
-+ or r0, r0
|
|
|
-+ or r0, r0
|
|
|
---- /dev/null
|
|
|
-+++ b/src/thread/sh/atomics.s
|
|
|
-@@ -0,0 +1,65 @@
|
|
|
-+/* Contract for all versions is same as cas.l r2,r3,@r0
|
|
|
-+ * pr and r1 are also clobbered (by jsr & r1 as temp).
|
|
|
-+ * r0,r2,r4-r15 must be preserved.
|
|
|
-+ * r3 contains result (==r2 iff cas succeeded). */
|
|
|
-+
|
|
|
-+ .align 2
|
|
|
-+.global __sh_cas_gusa
|
|
|
-+.hidden __sh_cas_gusa
|
|
|
-+__sh_cas_gusa:
|
|
|
-+ mov.l r5,@-r15
|
|
|
-+ mov.l r4,@-r15
|
|
|
-+ mov r0,r4
|
|
|
-+ mova 1f,r0
|
|
|
-+ mov r15,r1
|
|
|
-+ mov #(0f-1f),r15
|
|
|
-+0: mov.l @r4,r5
|
|
|
-+ cmp/eq r5,r2
|
|
|
-+ bf 1f
|
|
|
-+ mov.l r3,@r4
|
|
|
-+1: mov r1,r15
|
|
|
-+ mov r5,r3
|
|
|
-+ mov r4,r0
|
|
|
-+ mov.l @r15+,r4
|
|
|
-+ rts
|
|
|
-+ mov.l @r15+,r5
|
|
|
-+
|
|
|
-+.global __sh_cas_llsc
|
|
|
-+.hidden __sh_cas_llsc
|
|
|
-+__sh_cas_llsc:
|
|
|
-+ mov r0,r1
|
|
|
-+ synco
|
|
|
-+0: movli.l @r1,r0
|
|
|
-+ cmp/eq r0,r2
|
|
|
-+ bf 1f
|
|
|
-+ mov r3,r0
|
|
|
-+ movco.l r0,@r1
|
|
|
-+ bf 0b
|
|
|
-+ mov r2,r0
|
|
|
-+1: synco
|
|
|
-+ mov r0,r3
|
|
|
-+ rts
|
|
|
-+ mov r1,r0
|
|
|
-+
|
|
|
-+.global __sh_cas_imask
|
|
|
-+.hidden __sh_cas_imask
|
|
|
-+__sh_cas_imask:
|
|
|
-+ mov r0,r1
|
|
|
-+ stc sr,r0
|
|
|
-+ mov.l r0,@-r15
|
|
|
-+ or #0xf0,r0
|
|
|
-+ ldc r0,sr
|
|
|
-+ mov.l @r1,r0
|
|
|
-+ cmp/eq r0,r2
|
|
|
-+ bf 1f
|
|
|
-+ mov.l r3,@r1
|
|
|
-+1: ldc.l @r15+,sr
|
|
|
-+ mov r0,r3
|
|
|
-+ rts
|
|
|
-+ mov r1,r0
|
|
|
-+
|
|
|
-+.global __sh_cas_cas_l
|
|
|
-+.hidden __sh_cas_cas_l
|
|
|
-+__sh_cas_cas_l:
|
|
|
-+ rts
|
|
|
-+ .word 0x2323 /* cas.l r2,r3,@r0 */
|
|
|
---- a/src/thread/sh/syscall_cp.s
|
|
|
-+++ b/src/thread/sh/syscall_cp.s
|
|
|
-@@ -14,17 +14,8 @@ __syscall_cp_asm:
|
|
|
- __cp_begin:
|
|
|
- mov.l @r4, r4
|
|
|
- tst r4, r4
|
|
|
-- bt 2f
|
|
|
--
|
|
|
-- mov.l L1, r0
|
|
|
-- braf r0
|
|
|
-- nop
|
|
|
--1:
|
|
|
--
|
|
|
--.align 2
|
|
|
--L1: .long __cancel@PLT-(1b-.)
|
|
|
--
|
|
|
--2: mov r5, r3
|
|
|
-+ bf __cp_cancel
|
|
|
-+ mov r5, r3
|
|
|
- mov r6, r4
|
|
|
- mov r7, r5
|
|
|
- mov.l @r15, r6
|
|
|
-@@ -43,3 +34,12 @@ __cp_end:
|
|
|
-
|
|
|
- rts
|
|
|
- nop
|
|
|
-+
|
|
|
-+__cp_cancel:
|
|
|
-+ mov.l 2f, r0
|
|
|
-+ braf r0
|
|
|
-+ nop
|
|
|
-+1:
|
|
|
-+
|
|
|
-+.align 2
|
|
|
-+2: .long __cancel@PCREL-(1b-.)
|
|
|
---- a/src/thread/x32/syscall_cp.s
|
|
|
-+++ b/src/thread/x32/syscall_cp.s
|
|
|
-@@ -14,7 +14,7 @@ __syscall_cp_internal:
|
|
|
- __cp_begin:
|
|
|
- mov (%rdi),%eax
|
|
|
- test %eax,%eax
|
|
|
-- jnz __cancel
|
|
|
-+ jnz __cp_cancel
|
|
|
- mov %rdi,%r11
|
|
|
- mov %rsi,%rax
|
|
|
- mov %rdx,%rdi
|
|
|
-@@ -27,3 +27,5 @@ __cp_begin:
|
|
|
- syscall
|
|
|
- __cp_end:
|
|
|
- ret
|
|
|
-+__cp_cancel:
|
|
|
-+ jmp __cancel
|
|
|
---- /dev/null
|
|
|
-+++ b/src/thread/x32/syscall_cp_fixup.c
|
|
|
-@@ -0,0 +1,38 @@
|
|
|
-+#include <sys/syscall.h>
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+long __syscall_cp_internal(volatile void*, long long, long long, long long, long long,
|
|
|
-+ long long, long long, long long);
|
|
|
-+
|
|
|
-+struct __timespec { long long tv_sec; long tv_nsec; };
|
|
|
-+struct __timespec_kernel { long long tv_sec; long long tv_nsec; };
|
|
|
-+#define __tsc(X) ((struct __timespec*)(unsigned long)(X))
|
|
|
-+#define __fixup(X) do { if(X) { \
|
|
|
-+ ts->tv_sec = __tsc(X)->tv_sec; \
|
|
|
-+ ts->tv_nsec = __tsc(X)->tv_nsec; \
|
|
|
-+ (X) = (unsigned long)ts; } } while(0)
|
|
|
-+
|
|
|
-+__attribute__((__visibility__("hidden")))
|
|
|
-+long __syscall_cp_asm (volatile void * foo, long long n, long long a1, long long a2, long long a3,
|
|
|
-+ long long a4, long long a5, long long a6)
|
|
|
-+{
|
|
|
-+ struct __timespec_kernel ts[1];
|
|
|
-+ switch (n) {
|
|
|
-+ case SYS_mq_timedsend: case SYS_mq_timedreceive: case SYS_pselect6:
|
|
|
-+ __fixup(a5);
|
|
|
-+ break;
|
|
|
-+ case SYS_futex:
|
|
|
-+ if((a2 & (~128 /* FUTEX_PRIVATE_FLAG */)) == 0 /* FUTEX_WAIT */)
|
|
|
-+ __fixup(a4);
|
|
|
-+ break;
|
|
|
-+ case SYS_clock_nanosleep:
|
|
|
-+ case SYS_rt_sigtimedwait: case SYS_ppoll:
|
|
|
-+ __fixup(a3);
|
|
|
-+ break;
|
|
|
-+ case SYS_nanosleep:
|
|
|
-+ __fixup(a1);
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
-+ return __syscall_cp_internal(foo, n, a1, a2, a3, a4, a5, a6);
|
|
|
-+}
|
|
|
-+
|
|
|
---- a/src/thread/x86_64/syscall_cp.s
|
|
|
-+++ b/src/thread/x86_64/syscall_cp.s
|
|
|
-@@ -14,7 +14,7 @@ __syscall_cp_asm:
|
|
|
- __cp_begin:
|
|
|
- mov (%rdi),%eax
|
|
|
- test %eax,%eax
|
|
|
-- jnz __cancel
|
|
|
-+ jnz __cp_cancel
|
|
|
- mov %rdi,%r11
|
|
|
- mov %rsi,%rax
|
|
|
- mov %rdx,%rdi
|
|
|
-@@ -27,3 +27,5 @@ __cp_begin:
|
|
|
- syscall
|
|
|
- __cp_end:
|
|
|
- ret
|
|
|
-+__cp_cancel:
|
|
|
-+ jmp __cancel
|
|
|
---- a/src/time/clock_gettime.c
|
|
|
-+++ b/src/time/clock_gettime.c
|
|
|
-@@ -5,37 +5,54 @@
|
|
|
- #include "libc.h"
|
|
|
- #include "atomic.h"
|
|
|
-
|
|
|
--static int sc_clock_gettime(clockid_t clk, struct timespec *ts)
|
|
|
-+#ifdef VDSO_CGT_SYM
|
|
|
-+
|
|
|
-+void *__vdsosym(const char *, const char *);
|
|
|
-+
|
|
|
-+static void *volatile vdso_func;
|
|
|
-+
|
|
|
-+static int cgt_init(clockid_t clk, struct timespec *ts)
|
|
|
- {
|
|
|
-- int r = __syscall(SYS_clock_gettime, clk, ts);
|
|
|
-- if (!r) return r;
|
|
|
-- if (r == -ENOSYS) {
|
|
|
-- if (clk == CLOCK_REALTIME) {
|
|
|
-- __syscall(SYS_gettimeofday, ts, 0);
|
|
|
-- ts->tv_nsec = (int)ts->tv_nsec * 1000;
|
|
|
-- return 0;
|
|
|
-- }
|
|
|
-- r = -EINVAL;
|
|
|
-- }
|
|
|
-- errno = -r;
|
|
|
-- return -1;
|
|
|
-+ void *p = __vdsosym(VDSO_CGT_VER, VDSO_CGT_SYM);
|
|
|
-+ int (*f)(clockid_t, struct timespec *) =
|
|
|
-+ (int (*)(clockid_t, struct timespec *))p;
|
|
|
-+ a_cas_p(&vdso_func, (void *)cgt_init, p);
|
|
|
-+ return f ? f(clk, ts) : -ENOSYS;
|
|
|
- }
|
|
|
-
|
|
|
--void *__vdsosym(const char *, const char *);
|
|
|
-+static void *volatile vdso_func = (void *)cgt_init;
|
|
|
-+
|
|
|
-+#endif
|
|
|
-
|
|
|
- int __clock_gettime(clockid_t clk, struct timespec *ts)
|
|
|
- {
|
|
|
-+ int r;
|
|
|
-+
|
|
|
- #ifdef VDSO_CGT_SYM
|
|
|
-- static int (*volatile cgt)(clockid_t, struct timespec *);
|
|
|
-- if (!cgt) {
|
|
|
-- void *f = __vdsosym(VDSO_CGT_VER, VDSO_CGT_SYM);
|
|
|
-- if (!f) f = (void *)sc_clock_gettime;
|
|
|
-- a_cas_p(&cgt, 0, f);
|
|
|
-+ int (*f)(clockid_t, struct timespec *) =
|
|
|
-+ (int (*)(clockid_t, struct timespec *))vdso_func;
|
|
|
-+ if (f) {
|
|
|
-+ r = f(clk, ts);
|
|
|
-+ if (!r) return r;
|
|
|
-+ if (r == -EINVAL) return __syscall_ret(r);
|
|
|
-+ /* Fall through on errors other than EINVAL. Some buggy
|
|
|
-+ * vdso implementations return ENOSYS for clocks they
|
|
|
-+ * can't handle, rather than making the syscall. This
|
|
|
-+ * also handles the case where cgt_init fails to find
|
|
|
-+ * a vdso function to use. */
|
|
|
- }
|
|
|
-- return cgt(clk, ts);
|
|
|
--#else
|
|
|
-- return sc_clock_gettime(clk, ts);
|
|
|
- #endif
|
|
|
-+
|
|
|
-+ r = __syscall(SYS_clock_gettime, clk, ts);
|
|
|
-+ if (r == -ENOSYS) {
|
|
|
-+ if (clk == CLOCK_REALTIME) {
|
|
|
-+ __syscall(SYS_gettimeofday, ts, 0);
|
|
|
-+ ts->tv_nsec = (int)ts->tv_nsec * 1000;
|
|
|
-+ return 0;
|
|
|
-+ }
|
|
|
-+ r = -EINVAL;
|
|
|
-+ }
|
|
|
-+ return __syscall_ret(r);
|
|
|
- }
|
|
|
-
|
|
|
- weak_alias(__clock_gettime, clock_gettime);
|