17862 lines
		
	
	
		
			436 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			17862 lines
		
	
	
		
			436 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| --- 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,111 @@
 | |
| +.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
 | |
| +.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);
 | 
