├── .gitignore ├── lib ├── libutrace │ ├── ut_test.out │ ├── ut_test_core.u │ ├── ut_test.u │ ├── ut_buf.h │ ├── ut_prof.c │ ├── ut_obj.h │ ├── ut_test.sh │ ├── ut_subr.h │ ├── ut_pcb.h │ ├── ut_file.h │ ├── Makefile │ ├── utrace_impl.h │ ├── ut_open.c │ ├── ut_file.c │ ├── ut_test.c │ ├── ut_subr.c │ ├── ut_buf.c │ ├── ut_parser.h │ ├── ut_vm.h │ ├── ut_pcb.c │ ├── ut_parser.c │ └── ut_cc.c ├── libtree │ ├── Makefile │ └── tree.h ├── libunuma │ ├── Makefile │ └── unuma.h ├── Makefile ├── libvmem_malloc │ ├── Makefile │ └── malloc.c ├── libbson │ ├── Makefile │ ├── json.h │ ├── utf.h │ └── utf.c ├── libhrtime │ ├── Makefile │ ├── hrtime.h │ ├── hrtime_impl.h │ ├── hrtime_x86.h │ └── hrtime_arm.c ├── libvmem │ ├── vmem_cpuid.c │ ├── vmem_thread.c │ ├── vmem_cpuid.h │ ├── vmem_variable.c │ ├── vmem_object.c │ ├── Makefile │ ├── vmem_unuma.c │ ├── vmem_cd.c │ ├── vmem_mmap.c │ ├── vmem_verbose.c │ ├── vmem_printf.c │ ├── vmem_libc.c │ ├── vmem_sleep.c │ ├── vmem_heap.c │ ├── vmem_root.c │ └── vmem.h ├── Makefile.lib ├── libustat │ ├── Makefile │ ├── ustat_hash_impl.h │ ├── ustat_hash.h │ ├── ustat_ms.h │ ├── ustat_hg.h │ ├── ustat_io.h │ └── ustat_impl.h └── libucore │ ├── nt_fpregset.c │ ├── nt_prxfpreg.c │ ├── nt_xstate.c │ ├── Makefile │ ├── ucore.h │ ├── nt_auxv.c │ ├── ucore_test.c │ ├── nt_prpsinfo.c │ ├── nt_prstatus.c │ ├── ucore_test.sh │ └── ucore_impl.h ├── Makefile ├── cmd ├── Makefile ├── Makefile.cmd ├── ustat │ └── Makefile └── qat │ ├── Makefile │ └── qat.xsd ├── Makefile.subdirs ├── Makefile.x86_64 ├── include ├── units.h ├── p2.h ├── getpcstack.h ├── atomic.h └── list.h └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .nfs* 2 | *.[ao] 3 | *~ 4 | *.org 5 | webrev/* 6 | webrev.files 7 | -------------------------------------------------------------------------------- /lib/libutrace/ut_test.out: -------------------------------------------------------------------------------- 1 | x=1 2 | foo() 3 | main() 4 | libc.so.6`__libc_start_main() 5 | 6 | x=2 7 | bar() 8 | foo() 9 | main() 10 | libc.so.6`__libc_start_main() 11 | 12 | baz() 13 | "x=%d" 14 | x=3 15 | errno=123 (No medium found) 16 | caller=bar 17 | cycles=c1c1c1c1c1c1c1c1 18 | hrtime=d1d1d1d1d1d1d1d1 19 | cpuid=0 20 | prid=0 21 | EV_BAZ 22 | eventid=2 23 | lib/libutrace/ut_test.c 24 | 57 25 | x=3 26 | baz() 27 | bar() 28 | foo() 29 | main() 30 | libc.so.6`__libc_start_main() 31 | 32 | baz(3) 33 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | SUBDIRS := lib cmd 17 | include Makefile.subdirs 18 | -------------------------------------------------------------------------------- /cmd/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | SUBDIRS := qat ustat 17 | include ../Makefile.subdirs 18 | -------------------------------------------------------------------------------- /lib/libtree/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | include ../../Makefile.x86_64 18 | 19 | LIB := tree 20 | SRCS := tree.c 21 | 22 | include ../Makefile.lib 23 | -------------------------------------------------------------------------------- /lib/libunuma/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | include ../../Makefile.x86_64 18 | 19 | LIB := unuma 20 | SRCS := unuma.c 21 | 22 | include ../Makefile.lib 23 | -------------------------------------------------------------------------------- /Makefile.subdirs: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | all: TARGET += all 17 | clean: TARGET += clean 18 | clobber: TARGET += clobber 19 | 20 | all clean clobber: $(SUBDIRS) 21 | 22 | $(SUBDIRS): FRC 23 | @cd $@ && pwd && $(MAKE) $(TARGET) 24 | 25 | FRC: 26 | -------------------------------------------------------------------------------- /lib/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | SUBDIRS := \ 18 | libtree \ 19 | libhrtime \ 20 | libunuma \ 21 | libvmem \ 22 | libvmem_malloc \ 23 | libbson \ 24 | libustat \ 25 | libutrace \ 26 | libucore 27 | 28 | include ../Makefile.subdirs 29 | -------------------------------------------------------------------------------- /lib/libvmem_malloc/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | include ../../Makefile.x86_64 18 | 19 | LIB := vmem_malloc 20 | SRCS := malloc.c 21 | 22 | CFLAGS += -I../libvmem 23 | CFLAGS += -I../libunuma 24 | 25 | LDLIBS += -L../libvmem 26 | 27 | include ../Makefile.lib 28 | -------------------------------------------------------------------------------- /cmd/Makefile.cmd: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | OBJS := $(SRCS:%.c=%.o) 17 | 18 | all: $(CMD) 19 | 20 | $(CMD): $(OBJS) 21 | $(CC) $(CFLAGS) $(OBJS) -o $@ $(LDLIBS) 22 | 23 | %.o: %.c 24 | $(CC) $(CFLAGS) -c $< 25 | 26 | clean: 27 | rm -f $(OBJS) 28 | 29 | clobber: clean 30 | rm -f $(CMD) 31 | -------------------------------------------------------------------------------- /lib/libbson/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | include ../../Makefile.x86_64 17 | 18 | LIB := bson 19 | SRCS := bson.c bson_io.c json.c utf.c 20 | 21 | CFLAGS += -I../libunuma 22 | CFLAGS += -I../libvmem 23 | 24 | LDLIBS += -L../libunuma 25 | LDLIBS += -L../libvmem 26 | 27 | include ../Makefile.lib 28 | -------------------------------------------------------------------------------- /lib/libhrtime/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | include ../../Makefile.x86_64 17 | 18 | LIB := hrtime 19 | SRCS := hrtime.c 20 | LDLIBS += -lrt 21 | 22 | ifeq ($(ARCH),x86_64) 23 | SRCS += hrtime_x86.c 24 | endif 25 | 26 | ifeq ($(ARCH),arm) 27 | SRCS += hrtime_arm.c 28 | endif 29 | 30 | include ../Makefile.lib 31 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_cpuid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | int 23 | cpuid_get_cpu(void) 24 | { 25 | return (sched_getcpu()); 26 | } 27 | 28 | int 29 | cpuid_get_num_conf_cpus(void) 30 | { 31 | return (int)sysconf(_SC_NPROCESSORS_ONLN); 32 | } 33 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_thread.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * ============================================================================ 19 | * Thread operations 20 | * ============================================================================ 21 | */ 22 | #define VMEM_THREAD_OPS 23 | 24 | #include "vmem_magazine.c" 25 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_cpuid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _VMEM_CPUID_H 18 | #define _VMEM_CPUID_H 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | extern int cpuid_get_num_conf_cpus(void); 25 | extern int cpuid_get_cpu(void); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif /* _VMEM_CPUID_H */ 32 | -------------------------------------------------------------------------------- /lib/libutrace/ut_test_core.u: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | on event:"EV_FOO" 18 | { 19 | trace(file, line); 20 | abort(); 21 | } 22 | 23 | on event:"EV_BAR" 24 | { 25 | trace(cycles, hrtime, cpuid, tid, prid, event, eventid); 26 | } 27 | 28 | on event:"EV_BAZ" 29 | { 30 | trace(function, format, args, errno, caller, frame, stack); 31 | } 32 | -------------------------------------------------------------------------------- /lib/Makefile.lib: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | SOLIB := lib$(LIB).so 17 | OBJS := $(SRCS:%.c=%.o) 18 | CFLAGS += -fPIC 19 | 20 | all: $(SOLIB) 21 | 22 | $(SOLIB): $(OBJS) 23 | $(CC) $(CFLAGS) $(OBJS) -o $@ -shared -Wl,-soname,$(SOLIB) $(LDLIBS) 24 | 25 | %.o: %.c 26 | $(CC) $(CFLAGS) -c $< 27 | 28 | clean: 29 | rm -f $(OBJS) $(CLEANFILES) 30 | 31 | clobber: clean 32 | rm -f $(SOLIB) $(CLOBBERFILES) 33 | -------------------------------------------------------------------------------- /Makefile.x86_64: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | ARCH := x86_64 17 | TOOLS := /home/build/x86_64-el7-tools/native-4.7.3-1 18 | 19 | CC := $(TOOLS)/bin/gcc 20 | FLEX := flex 21 | BISON := bison 22 | 23 | CFLAGS := -m64 24 | CFLAGS += -g -fno-omit-frame-pointer 25 | CFLAGS += -Wvla 26 | CFLAGS += -O3 27 | CFLAGS += -std=gnu99 -D_GNU_SOURCE -D__USE_LARGEFILE64 28 | CFLAGS += -I. -I../../include 29 | 30 | LDLIBS := 31 | -------------------------------------------------------------------------------- /lib/libustat/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | include ../../Makefile.x86_64 18 | 19 | LIB := ustat 20 | SRCS := ustat.c ustat_hash.c ustat_hg.c ustat_imp.c ustat_io.c ustat_ms.c 21 | CFLAGS += -Wno-missing-field-initializers -Wno-switch-enum 22 | 23 | CFLAGS += -I../libhrtime 24 | CFLAGS += -I../libunuma 25 | CFLAGS += -I../libvmem 26 | CFLAGS += -I../libbson 27 | CFLAGS += -I../libucore 28 | 29 | include ../Makefile.lib 30 | -------------------------------------------------------------------------------- /lib/libucore/nt_fpregset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | ssize_t 20 | nt_fpregset_size(NElf_Word type, int fd, off_t off, pid_t tid) 21 | { 22 | return (ucore_note_size(type, 23 | "CORE", sizeof (elf_fpregset_t))); 24 | } 25 | 26 | ssize_t 27 | nt_fpregset_dump(NElf_Word type, int fd, off_t off, pid_t tid) 28 | { 29 | return (ucore_note_regs(type, fd, off, 30 | tid, "CORE", sizeof (elf_fpregset_t))); 31 | } 32 | -------------------------------------------------------------------------------- /lib/libucore/nt_prxfpreg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | ssize_t 20 | nt_prxfpreg_size(NElf_Word type, int fd, off_t off, pid_t tid) 21 | { 22 | return (ucore_note_size(type, 23 | "CORE", sizeof (elf_fpxregset_t))); 24 | } 25 | 26 | ssize_t 27 | nt_prxfpreg_dump(NElf_Word type, int fd, off_t off, pid_t tid) 28 | { 29 | return (ucore_note_regs(type, fd, off, 30 | tid, "CORE", sizeof (elf_fpxregset_t))); 31 | } 32 | -------------------------------------------------------------------------------- /lib/libutrace/ut_test.u: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | on event:"EV_BAZ" 18 | { 19 | print(function); 20 | print(format); 21 | print(args); 22 | print(errno); 23 | print(caller); 24 | print(frame); 25 | print(cycles); 26 | print(hrtime); 27 | print(cpuid); 28 | print(tid); 29 | print(prid); 30 | print(event); 31 | print(eventid); 32 | print(file); 33 | print(line); 34 | } 35 | 36 | on event:"EV_*" 37 | { 38 | print(args); 39 | print(stack); 40 | } 41 | -------------------------------------------------------------------------------- /lib/libucore/nt_xstate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #define XSTATE_SIZE 0x340 /* as of %xmm, %ymm */ 20 | 21 | ssize_t 22 | nt_xstate_size(NElf_Word type, int fd, off_t off, pid_t tid) 23 | { 24 | return (ucore_note_size(type, "LINUX", XSTATE_SIZE)); 25 | } 26 | 27 | ssize_t 28 | nt_xstate_dump(NElf_Word type, int fd, off_t off, pid_t tid) 29 | { 30 | return (ucore_note_regs(type, fd, off, tid, "LINUX", XSTATE_SIZE)); 31 | } 32 | -------------------------------------------------------------------------------- /lib/libucore/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | include ../../Makefile.x86_64 17 | 18 | LIB := ucore 19 | SRCS := ucore.c nt_auxv.c nt_fpregset.c nt_prpsinfo.c nt_prstatus.c nt_xstate.c 20 | LDLIBS += -Wl,-znodelete 21 | 22 | ifneq ($(DIST),sles11sp) 23 | CFLAGS += -DNEED_PTRACE_REGSET=1 24 | endif 25 | 26 | ifneq ($(ARCH),x86_64) 27 | SRCS += nt_prxfpreg.c 28 | endif 29 | 30 | CFLAGS += -I../libhrtime 31 | CFLAGS += -I../libunuma 32 | CFLAGS += -I../libvmem 33 | CFLAGS += -I../libutrace 34 | 35 | include ../Makefile.lib 36 | -------------------------------------------------------------------------------- /lib/libbson/json.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _JSON_H 18 | #define _JSON_H 19 | 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | extern int32_t json_string_to_utf8(const char *j, char q, char *s, int m); 27 | extern int32_t json_string_from_utf8(char *j, char q, const char *s, int len); 28 | extern int json_parse(bson_t *b, const char **j, char q, off_t d, int a, 29 | json_parse_cb *cb, void *arg); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | #endif /* _JSON_H */ 36 | -------------------------------------------------------------------------------- /cmd/ustat/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | include ../../Makefile.x86_64 17 | 18 | CMD := ustat 19 | SRCS := ustat.c 20 | 21 | CFLAGS += -I../../lib/libunuma 22 | CFLAGS += -I../../lib/libvmem 23 | CFLAGS += -I../../lib/libbson 24 | CFLAGS += -I../../lib/libustat 25 | 26 | LDLIBS += -L../../lib/libhrtime -lhrtime 27 | LDLIBS += -L../../lib/libtree -ltree 28 | LDLIBS += -L../../lib/libunuma -lunuma 29 | LDLIBS += -L../../lib/libvmem -lvmem 30 | LDLIBS += -L../../lib/libbson -lbson 31 | LDLIBS += -L../../lib/libustat -lustat 32 | 33 | LDLIBS += -lpthread -lm 34 | 35 | include ../Makefile.cmd 36 | -------------------------------------------------------------------------------- /lib/libucore/ucore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UCORE_H 18 | #define _UCORE_H 19 | 20 | #include 21 | #include 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | typedef void * ucore_handle_t; 28 | 29 | extern bool ucore_enable; 30 | 31 | extern void ucore_exclude(const void *, size_t); 32 | extern void ucore_include(const void *, size_t); 33 | 34 | extern ucore_handle_t ucore_onfault(void (*)(void *), void *); 35 | extern void ucore_nofault(ucore_handle_t); 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | 41 | #endif /* _UCORE_H */ 42 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_variable.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | /* 20 | * ============================================================================ 21 | * Variable-size operations 22 | * ============================================================================ 23 | */ 24 | static int 25 | vmem_variable_init(vmem_t *vm) 26 | { 27 | vm->vm_ops = vmem_seg_ops; 28 | 29 | return (vm->vm_ops.vop_init(vm)); 30 | } 31 | 32 | const vmem_ops_t vmem_variable_ops = { 33 | .vop_init = vmem_variable_init, 34 | .vop_name = "variable", 35 | .vop_attr = VMEM_OP_BASE | VMEM_OP_ALIAS 36 | }; 37 | -------------------------------------------------------------------------------- /include/units.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UNITS_H 18 | #define _UNITS_H 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #define FP_SEC 1.0 25 | #define FP_MILLISEC 1000.0 26 | #define FP_MICROSEC 1000000.0 27 | #define FP_NANOSEC 1000000000.0 28 | 29 | #define U_SEC 1ULL 30 | #define U_MILLISEC 1000ULL 31 | #define U_MICROSEC 1000000ULL 32 | #define U_NANOSEC 1000000000ULL 33 | 34 | #define U_B 1UL 35 | #define U_KB 1024UL 36 | #define U_MB 1048576UL 37 | #define U_GB 1073741824UL 38 | #define U_TB 1099511627776ULL 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif /* _UNITS_H */ 45 | -------------------------------------------------------------------------------- /lib/libutrace/ut_buf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UT_BUF_H 18 | #define _UT_BUF_H 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | typedef struct ut_buf { 25 | uint8_t *utbuf_base; 26 | uint8_t *utbuf_bend; 27 | size_t utbuf_size; 28 | size_t utbuf_free; 29 | uint8_t *utbuf_rptr; 30 | uint8_t *utbuf_wptr; 31 | } ut_buf_t; 32 | 33 | extern ut_buf_t *utrace_buf_create(size_t); 34 | extern void utrace_buf_destroy(ut_buf_t *); 35 | extern void utrace_buf_write(ut_buf_t *, const void *, size_t); 36 | extern void utrace_buf_erase(ut_buf_t *, size_t); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif /* _UT_BUF_H */ 43 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_object.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | /* 20 | * ============================================================================ 21 | * Object (fixed-size) operations 22 | * ============================================================================ 23 | */ 24 | static int 25 | vmem_object_init(vmem_t *vm) 26 | { 27 | if (vm->vm_object == 0) 28 | return (-1); 29 | 30 | vm->vm_ops = vmem_slab_ops; 31 | 32 | if (vm->vm_ops.vop_init(vm) == 0) 33 | return (0); 34 | 35 | vm->vm_ops = vmem_seg_ops; 36 | 37 | return (vm->vm_ops.vop_init(vm)); 38 | } 39 | 40 | const vmem_ops_t vmem_object_ops = { 41 | .vop_init = vmem_object_init, 42 | .vop_name = "object", 43 | .vop_attr = VMEM_OP_BASE | VMEM_OP_ALIAS 44 | }; 45 | -------------------------------------------------------------------------------- /lib/libvmem_malloc/malloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | void * 24 | malloc(size_t size) 25 | { 26 | return (vmem_libc_malloc(size)); 27 | } 28 | 29 | void * 30 | calloc(size_t nelem, size_t elsize) 31 | { 32 | return (vmem_libc_calloc(nelem, elsize)); 33 | } 34 | 35 | void * 36 | memalign(size_t align, size_t size) 37 | { 38 | return (vmem_libc_memalign(align, size)); 39 | } 40 | 41 | void * 42 | valloc(size_t size) 43 | { 44 | return (vmem_libc_valloc(size)); 45 | } 46 | 47 | void 48 | free(void *buf) 49 | { 50 | vmem_libc_free(buf); 51 | } 52 | 53 | void * 54 | realloc(void *buf, size_t newsize) 55 | { 56 | return (vmem_libc_realloc(buf, newsize)); 57 | } 58 | -------------------------------------------------------------------------------- /lib/libhrtime/hrtime.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _HRTIME_H 18 | #define _HRTIME_H 19 | 20 | #include 21 | #include 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | typedef enum hrclock { 28 | HRCLOCK_TSC, /* x86 RDTSC or equivalent */ 29 | HRCLOCK_MONOTONIC, /* clock_gettime(CLOCK_MONOTONIC) */ 30 | } hrclock_t; 31 | 32 | extern uint64_t gethrcycles(void); 33 | extern uint64_t gethrtime(void); 34 | extern uint32_t gethrfreq(void); /* in KHz */ 35 | extern uint64_t hrcyctons(uint64_t cycles); 36 | extern uint64_t hrcyctonsm(uint64_t cycles, uint64_t cycle_mult); 37 | extern uint32_t gethrcycle_mult(void); 38 | extern hrclock_t gethrclock(void); 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif /* _HRTIME_H */ 45 | -------------------------------------------------------------------------------- /lib/libvmem/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | include ../../Makefile.x86_64 18 | 19 | LIB := vmem 20 | CFLAGS += -Wno-missing-field-initializers 21 | LDLIBS += -lunuma -lhrtime -ltree -lpthread -ldl 22 | 23 | CFLAGS += -I../libtree 24 | CFLAGS += -I../libhrtime 25 | CFLAGS += -I../libunuma 26 | 27 | LDLIBS += -L../libtree 28 | LDLIBS += -L../libhrtime 29 | LDLIBS += -L../libunuma 30 | 31 | SRCS := \ 32 | vmem.c \ 33 | vmem_cd.c \ 34 | vmem_cpuid.c \ 35 | vmem_debug.c \ 36 | vmem_heap.c \ 37 | vmem_libc.c \ 38 | vmem_magazine.c \ 39 | vmem_mmap.c \ 40 | vmem_object.c \ 41 | vmem_printf.c \ 42 | vmem_root.c \ 43 | vmem_seg.c \ 44 | vmem_slab.c \ 45 | vmem_sleep.c \ 46 | vmem_thread.c \ 47 | vmem_unuma.c \ 48 | vmem_variable.c \ 49 | vmem_verbose.c 50 | 51 | include ../Makefile.lib 52 | -------------------------------------------------------------------------------- /lib/libutrace/ut_prof.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | 21 | /* 22 | * Default utrace profiling stub callbacks. 23 | */ 24 | static void 25 | utrace_prof_begin(unsigned slot) 26 | { 27 | } 28 | 29 | static void 30 | utrace_prof_end(unsigned slot) 31 | { 32 | } 33 | 34 | /* 35 | * The active utrace profiling ops. 36 | */ 37 | utrace_prof_ops_t UT_prof; 38 | 39 | /* 40 | * Sets the utrace profiling callbacks. 41 | * 42 | * If ops is NULL then the default callbacks are set. 43 | */ 44 | void 45 | utrace_profile(utrace_prof_ops_t *ops) 46 | { 47 | if (ops != NULL) { 48 | (void) memcpy(&UT_prof, ops, sizeof (UT_prof)); 49 | } else { 50 | UT_prof.utpf_begin = utrace_prof_begin; 51 | UT_prof.utpf_end = utrace_prof_end; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/libbson/utf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UTF_H 18 | #define _UTF_H 19 | 20 | #include 21 | #include 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | extern int unicode_is_sp(uint32_t u); 28 | extern int unicode_is_sp1(uint32_t u1); 29 | extern int unicode_is_sp2(uint32_t u2); 30 | extern void unicode_to_sp(uint32_t u, uint32_t *u1, uint32_t *u2); 31 | extern uint32_t unicode_from_sp(uint32_t u1, uint32_t u2); 32 | extern char *unicode_to_utf8_n(uint32_t u, char *s, int n); 33 | extern const char *unicode_from_utf8_n(uint32_t *u, const char *s, int n); 34 | extern char *unicode_to_utf8(uint32_t u, char *s); 35 | extern const char *unicode_from_utf8(uint32_t *u, const char *s); 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | 41 | #endif /* _UTF_H */ 42 | -------------------------------------------------------------------------------- /cmd/qat/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | all clean clobber: 18 | # shell script build, nothing to do 19 | 20 | # 21 | # For the self-test, give qat all the arguments necessary to run inside of the 22 | # build environment and use the test tree located here in our source directory. 23 | # To generate the golden result file test/test.xml when qat itself changes, 24 | # replace -g with -j (keeping the argument the same) -- this will report FAIL 25 | # as a result of the test tree itself generating failures, but will leave XML. 26 | # To debug -g failures, change -K to -k in TEST_ARGS to retain /tmp/qat* 27 | # 28 | TEST_ARGS_qat := \ 29 | -g $(SRCDIR)/test/test.xml \ 30 | -K \ 31 | -P ../$(SRCDIR)/test \ 32 | -R $(TOPDIR_FULL)/proto \ 33 | -S $(SRCDIR)/test/test.skip \ 34 | -u qat-test-self \ 35 | -x $(SRCDIR)/qat.xsd 36 | -------------------------------------------------------------------------------- /lib/libutrace/ut_obj.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UT_OBJ_H 18 | #define _UT_OBJ_H 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | typedef struct ut_obj { 25 | pthread_mutex_t utob_prlock; 26 | utrace_probe_t *utob_probev; 27 | size_t utob_probec; 28 | uint32_t utob_refs; 29 | void *utob_symtab; 30 | size_t utob_symlen; 31 | size_t utob_syment; 32 | char *utob_strtab; 33 | size_t utob_strlen; 34 | } ut_obj_t; 35 | 36 | extern void utrace_obj_init(ut_obj_t *); 37 | extern int utrace_obj_load(utrace_handle_t *, ut_obj_t *, const char *); 38 | extern void utrace_obj_free(ut_obj_t *); 39 | extern void utrace_obj_hold(ut_obj_t *); 40 | extern void utrace_obj_rele(ut_obj_t *); 41 | extern size_t utrace_obj_name(ut_obj_t *, uintptr_t, char *, size_t); 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif /* _UT_OBJ_H */ 48 | -------------------------------------------------------------------------------- /lib/libustat/ustat_hash_impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef USTAT_HASH_IMPL_H 18 | #define USTAT_HASH_IMPL_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | 25 | struct ustat_hash_entry 26 | { 27 | void *ushe_obj; // hash object 28 | ustat_struct_t *ushe_stat; // stats for the hash object 29 | struct ustat_hash_entry *ushe_next; // overflow entry 30 | }; 31 | 32 | 33 | // ustat hash table. 34 | struct ustat_hash 35 | { 36 | ustat_handle_t *ush_ustat_h; 37 | struct ustat_hash_entry *ush_table; 38 | struct ustat_hash_entry *ush_unused; // unused hash entries 39 | uint32_t ush_num_buckets; 40 | uint32_t ush_num_entries; 41 | pthread_mutex_t ush_lock; 42 | ustat_class_t ush_sclass; // ustat class for each hash entry's ushe_stat 43 | }; 44 | 45 | 46 | #endif // USTAT_HASH_IMPL_H 47 | -------------------------------------------------------------------------------- /lib/libucore/nt_auxv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | ssize_t 20 | nt_auxv_size(NElf_Word type, int fd, off_t off, pid_t tid) 21 | { 22 | ssize_t len; 23 | void *buf; 24 | 25 | if (tid != ucore_gettid()) 26 | return (0); /* only for the main thread */ 27 | 28 | buf = ucore_page_alloc(); 29 | len = ucore_slurp(UCORE_S_BIN, 30 | buf, ucore_pgsize, "/proc/%d/auxv", ucore_getpid()); 31 | 32 | ucore_page_free(buf); 33 | return (ucore_note_size(type, "CORE", len)); 34 | } 35 | 36 | ssize_t 37 | nt_auxv_dump(NElf_Word type, int fd, off_t off, pid_t tid) 38 | { 39 | ssize_t len; 40 | void *buf; 41 | 42 | if (tid != ucore_gettid()) 43 | return (0); /* only for the main thread */ 44 | 45 | buf = ucore_page_alloc(); 46 | len = ucore_slurp(UCORE_S_BIN, 47 | buf, ucore_pgsize, "/proc/%d/auxv", ucore_getpid()); 48 | len = ucore_note_dump(fd, off, type, "CORE", buf, len); 49 | 50 | ucore_page_free(buf); 51 | return (len); 52 | } 53 | -------------------------------------------------------------------------------- /include/p2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _P2_H 18 | #define _P2_H 19 | 20 | #ifndef __KERNEL__ 21 | #include 22 | #endif 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #define P2ALIGN(x, a) ((x) & -(__typeof__(x))(a)) 29 | #define P2PHASE(x, a) ((x) & ((a) - 1)) 30 | #define P2NPHASE(x, a) (-(x) & ((a) - 1)) 31 | #define P2ROUNDUP(x, a) (-(-(x) & -(__typeof__(x))(a))) 32 | #define P2END(x, a) (-(~(x) & -(__typeof__(x))(a))) 33 | #define P2PHASEUP(x, a, phase) \ 34 | ((phase) - (((phase) - (x)) & -(__typeof__(x))(a))) 35 | #define P2BOUNDARY(off, len, a) (((off) ^ ((off) + (len) - 1)) > (a) - 1) 36 | #define P2SAMEHIGHBIT(x, y) (((x) ^ (y)) < ((x) & (y))) 37 | #define P2CLEARLOWBIT(x) ((x) & ((x) - 1)) 38 | #define P2ALIGNOF(x) ((x) ^ ((x) & ((x) - 1))) 39 | 40 | #define IS_P2(x) (P2CLEARLOWBIT(x) == 0) 41 | #define IS_P2ALIGNED(p, a) ((((uintptr_t)(p)) & ((uintptr_t)(a) - 1)) == 0) 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif /* _P2_H */ 48 | -------------------------------------------------------------------------------- /lib/libutrace/ut_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -p 2 | 3 | # 4 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | # 20 | # Run ut_test with memory checking and leak checking enabled in libvmem. 21 | # Strip out functions offsets +0x which are likely to break if we upgrade 22 | # compilers or change compilation options, and diff the output against 23 | # something we have hand-verified to be corrected for our test program. 24 | # 25 | 26 | VMEM_DEBUG=all $OBJDIR/ut_test <$SRCDIR/ut_test.u | \ 27 | sed 's/+0x[0-9a-f]*//' | egrep -v '^(tid|frame)=' | diff -u $SRCDIR/ut_test.out - 28 | 29 | # Clean up cores first.. 30 | utfile=$PWD/$SRCDIR/ut_test_core.u 31 | rm -f $OBJDIR/core.[0-9]* 32 | if (cd $OBJDIR; VMEM_DEBUG=all ./ut_test 60 ) < $utfile > $OBJDIR/ut_test.out 2>$OBJDIR/ut_test.err ; then 33 | echo "unexpected success" 34 | exit 1 35 | fi 36 | count=0 37 | corepat=$OBJDIR/core.[0-9]* 38 | while ! [[ -r $(ls $corepat) ]] ; do 39 | echo $(date) $PWD $corepat not found 40 | sleep 1 41 | ((count+=1)) 42 | if [[ $count -gt 5 ]] ; then 43 | exit 1 44 | fi 45 | done 46 | 47 | -------------------------------------------------------------------------------- /lib/libutrace/ut_subr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UT_SUBR_H 18 | #define _UT_SUBR_H 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | extern ssize_t utrace_vtracef(char *, size_t, const char *, va_list) 25 | __attribute__((format(printf, 3, 0))); 26 | 27 | extern void utrace_vprintf(FILE *, const char *, va_list ap) 28 | __attribute__((format(printf, 2, 0))); 29 | 30 | extern void utrace_printf(FILE *, const char *, ...) 31 | __attribute__((format(printf, 2, 3))); 32 | 33 | extern void utrace_dprintf(const char *, ...) 34 | __attribute__((format(printf, 1, 2))); 35 | 36 | extern int utrace_verror(utrace_handle_t *, int, const char *, va_list) 37 | __attribute__((format(printf, 3, 0))); 38 | 39 | extern int utrace_error(utrace_handle_t *, int, const char *, ...) 40 | __attribute__((format(printf, 3, 4))); 41 | 42 | extern void *utrace_null(utrace_handle_t *, int, const char *, ...) 43 | __attribute__((format(printf, 3, 4))); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif /* _UT_SUBR_H */ 50 | -------------------------------------------------------------------------------- /lib/libucore/ucore_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include "ucore.h" 22 | 23 | bool ucore_enable = true; 24 | char rodata[16] = "rodata"; 25 | char bss[16]; 26 | char *heap; 27 | char *stk; 28 | 29 | int 30 | main(int argc, char *argv[]) 31 | { 32 | char s[16] = "stack"; 33 | pthread_attr_t attr; 34 | void *stackaddr; 35 | size_t stacksize; 36 | 37 | /* 38 | * This program reports its stack base and size so that surrounding 39 | * test logic will work properly. See ucore_test.sh. 40 | */ 41 | (void) pthread_attr_init(&attr); 42 | (void) pthread_getattr_np(pthread_self(), &attr); 43 | (void) pthread_attr_getstack(&attr, &stackaddr, &stacksize); 44 | (void) pthread_attr_destroy(&attr); 45 | (void) printf("stackbase=%p\n", stackaddr); 46 | (void) printf("stacksize=%lu\n", stacksize); 47 | fflush(stdout); 48 | 49 | (void) strcpy(bss, "bss"); 50 | heap = malloc(16); 51 | (void) strcpy(heap, "heap"); 52 | stk = s; 53 | 54 | volatile int *p = (int *)0xd5; 55 | return (*p); 56 | } 57 | -------------------------------------------------------------------------------- /lib/libutrace/ut_pcb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UT_PCB_H 18 | #define _UT_PCB_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | typedef struct ut_var { 30 | const char *var_name; 31 | uint8_t var_code; 32 | uint16_t var_type; 33 | void (*var_cook)(struct ut_pcb *, struct ut_node *); 34 | } ut_var_t; 35 | 36 | typedef struct ut_str { 37 | tree_node_t str_node; 38 | const ut_var_t *str_vref; 39 | char *str_data; 40 | size_t str_size; 41 | } ut_str_t; 42 | 43 | typedef struct ut_pcb { 44 | struct utrace_handle *pcb_hdl; 45 | tree_t pcb_strings; 46 | vmem_t *pcb_nodes; 47 | ut_node_t *pcb_root; 48 | int pcb_depth; 49 | FILE *pcb_stdin; 50 | int pcb_cstate; 51 | int pcb_braces; 52 | int pcb_bracks; 53 | int pcb_parens; 54 | int pcb_errs; 55 | int pcb_warns; 56 | } ut_pcb_t; 57 | 58 | extern const ut_str_t *utrace_pcb_string(ut_pcb_t *, const char *); 59 | extern void utrace_pcb_init(utrace_handle_t *, ut_pcb_t *, FILE *); 60 | extern void utrace_pcb_fini(utrace_handle_t *, ut_pcb_t *); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif /* _UT_PCB_H */ 67 | -------------------------------------------------------------------------------- /lib/libhrtime/hrtime_impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef HRTIME_IMPL_H 18 | #define HRTIME_IMPL_H 19 | 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | #define ATTR_TSC 0x1 /* cpus have tsc instruction */ 27 | #define ATTR_APM 0x2 /* cpus have advanced power mgmt */ 28 | #define ATTR_TSC_INVARIANT 0x4 /* cpus have invariant tsc */ 29 | #define ATTR_TSC_RATIO 0x8 /* cpus have invariant tsc ratio */ 30 | #define ATTR_ALL 0xF /* cpus have all required attrs */ 31 | 32 | #define NSEC_PER_MSEC (U_NANOSEC / U_MILLISEC) 33 | 34 | /* 35 | * Used to convert a cycle value to a nanosecond value via a shift. See tsc.c 36 | * ("Accelerators for sched_clock()") in the Linux kernel for a description of 37 | * why this value is appropriate. 38 | */ 39 | #define CYC_TO_NS_SCALE 10 40 | 41 | typedef uint64_t (*gethrtime_funcp_t)(void); 42 | typedef uint64_t (*gethrcycles_funcp_t)(void); 43 | 44 | extern hrclock_t hrtime_clock; 45 | extern uint32_t hrtime_cpu_attrs; 46 | extern uint32_t hrtime_clock_khz; /* clock rate in KHz */ 47 | extern gethrtime_funcp_t gethrtime_funcp; 48 | extern gethrcycles_funcp_t gethrcycles_funcp; 49 | 50 | extern void hrtime_init_cpu(void); 51 | extern int __attribute__ ((format(printf, 2, 3))) 52 | hrtime_error(int err2, const char *format, ...); 53 | extern void sethrcycle_mult(uint32_t mult); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif /* HRTIME_IMPL_H */ 60 | -------------------------------------------------------------------------------- /lib/libustat/ustat_hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef USTAT_HASH_H 18 | #define USTAT_HASH_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * The hash walk callback is passed the object and stat for each object, 32 | * as well as the user-defined value uval passed to ustat_hash_walk(). 33 | * If the callback returns true then continue walking, otherwise stop. 34 | */ 35 | typedef bool (*ustat_hash_walk_f)(void *obj, ustat_struct_t *stats, void *uval); 36 | typedef struct ustat_hash_entry ustat_hash_entry_t; 37 | typedef struct ustat_hash ustat_hash_t; 38 | 39 | 40 | extern ustat_hash_t *ustat_hash_alloc(ustat_handle_t *ustat_h, 41 | uint32_t num_buckets, const ustat_class_t *sclass); 42 | extern void ustat_hash_free(ustat_hash_t *h); 43 | 44 | // ustat_hash_find() and ustat_hash_walk() do not take the hash lock 45 | extern ustat_struct_t *ustat_hash_find(const ustat_hash_t *h, const void *obj); 46 | extern void ustat_hash_walk(ustat_hash_t *h, ustat_hash_walk_f cb, void *uval); 47 | 48 | extern ustat_struct_t *ustat_hash_add(ustat_hash_t *h, void *obj, 49 | const char *ename); 50 | 51 | extern void ustat_hash_remove(ustat_hash_t *h, void *obj); 52 | extern uint32_t ustat_hash_get_nentries(const ustat_hash_t *h); 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif // USTAT_HASH_H 59 | -------------------------------------------------------------------------------- /lib/libutrace/ut_file.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UT_FILE_H 18 | #define _UT_FILE_H 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | typedef enum ut_file_sect { 25 | UT_FILE_SECT_HDR, 26 | UT_FILE_SECT_PROBE, 27 | UT_FILE_SECT_STR, 28 | UT_FILE_SECT_CODE, 29 | UT_FILE_SECT_MAX 30 | } ut_file_sect_t; 31 | 32 | typedef struct ut_file_subs { 33 | uint8_t *utfs_ptr; 34 | size_t utfs_len; 35 | } ut_file_subs_t; 36 | 37 | typedef struct ut_file { 38 | ut_file_subs_t utfi_sect[UT_FILE_SECT_MAX]; 39 | uint8_t *utfi_data; 40 | size_t utfi_size; 41 | } ut_file_t; 42 | 43 | typedef struct ut_file_header { 44 | uint8_t utfh_ident[4]; 45 | uint16_t utfh_wsize; 46 | uint16_t utfh_border; 47 | uint32_t utfh_proff; 48 | uint32_t utfh_prlen; 49 | } ut_file_header_t; 50 | 51 | #define FHDR_IDENT_MAG0 0 52 | #define FHDR_IDENT_MAG1 1 53 | #define FHDR_IDENT_MAG2 2 54 | #define FHDR_IDENT_MAG3 3 55 | 56 | #define FHDR_IDMAG_MAG0 '\0' 57 | #define FHDR_IDMAG_MAG1 'U' 58 | #define FHDR_IDMAG_MAG2 'F' 59 | #define FHDR_IDMAG_MAG3 'O' 60 | 61 | typedef struct ut_file_probe { 62 | uint32_t utfp_event; 63 | uint32_t utfp_file; 64 | uint32_t utfp_line; 65 | uint32_t utfp_code; 66 | uint32_t utfp_clen; 67 | } ut_file_probe_t; 68 | 69 | extern void utrace_file_alloc(ut_file_t *); 70 | extern size_t utrace_file_write(ut_file_t *, 71 | ut_file_sect_t, const void *, size_t); 72 | extern size_t utrace_file_wroff(const ut_file_t *, ut_file_sect_t); 73 | 74 | #ifdef __cplusplus 75 | } 76 | #endif 77 | 78 | #endif /* _UT_FILE_H */ 79 | -------------------------------------------------------------------------------- /lib/libhrtime/hrtime_x86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef HRTIME_X86_H 18 | #define HRTIME_X86_H 19 | 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* 27 | * Definitions for the CPUID instruction. These are summarized in: 28 | * Intel Processor ID and the CPUID Instruction, Application Note 485 29 | */ 30 | #define CPUID_FCN_VID 0x00000000 /* CPUID 5.1.1 */ 31 | #define CPUID_FCN_SFF 0x00000001 /* CPUID 5.1.2 */ 32 | #define CPUID_FCN_MAX 0x80000000 /* CPUID 5.2.1 */ 33 | #define CPUID_FCN_APM 0x80000007 /* CPUID 5.2.6 */ 34 | 35 | #define CPUID_SIG_FAMILY(r) \ 36 | ((((r) >> 20) & 0xFF) + (((r) >> 8) & 0xF)) /* CPUID 5.1.2.2 E5-1 */ 37 | 38 | #define CPUID_SIG_MODEL(r) \ 39 | (((((r) >> 16) & 0xF) << 4) + (((r) >> 4) & 0xF)) /* CPUID 5.1.2.2 E5-2 */ 40 | 41 | #define CPUID_SFF_EDX_TSC (1 << 4) /* CPUID 5.1.2 */ 42 | #define CPUID_APM_EDX_TSC_INVARIANT (1 << 8) /* CPUID 5.2.6 */ 43 | 44 | #define MSR_PLATFORM_INFO 0xCE /* IA32_64 3B Tbl B-5 */ 45 | #define MSR_PLATFORM_INFO_NTRATIO(m) ((uint8_t)(m >> 8)) /* IA32_64 3B B-5 */ 46 | 47 | /* 48 | * Encoding of pread() offsets for use with the cpuid(4) and msr(4) devices. 49 | * These devices use fake offsets as input arguments and return the registers. 50 | */ 51 | #define CPUID_OFF(eax, ecx) (((uint64_t)ecx << 32) | (uint64_t)eax) 52 | #define MSR_OFF(ecx) ((uint64_t)ecx) 53 | 54 | typedef struct hrtime_regs { 55 | uint32_t r_eax; 56 | uint32_t r_ebx; 57 | uint32_t r_ecx; 58 | uint32_t r_edx; 59 | } hrtime_regs_t; 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif /* HRTIME_X86_H */ 66 | -------------------------------------------------------------------------------- /lib/libutrace/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | include ../../Makefile.x86_64 18 | 19 | LIB := utrace 20 | SRCS := \ 21 | ut_grammar.c \ 22 | ut_buf.c \ 23 | ut_cc.c \ 24 | ut_file.c \ 25 | ut_lex.c \ 26 | ut_obj.c \ 27 | ut_open.c \ 28 | ut_parser.c \ 29 | ut_pcb.c \ 30 | ut_probe.c \ 31 | ut_prof.c \ 32 | ut_subr.c 33 | 34 | ifeq ($(ARCH),x86_64) 35 | SRCS += ut_vm.c 36 | endif 37 | 38 | GENS := ut_grammar.c ut_grammar.h ut_lex.c 39 | CLEANFILES += $(GENS) ut_grammar.output 40 | 41 | CFLAGS += -I../libtree 42 | CFLAGS += -I../libhrtime 43 | CFLAGS += -I../libunuma 44 | CFLAGS += -I../libvmem 45 | 46 | .SECONDARY: $(GENS) 47 | include ../Makefile.lib 48 | 49 | ut_lex.o:: CFLAGS += -Wno-unused-function -Wno-redundant-decls 50 | ut_grammar.o:: CFLAGS += -Wno-redundant-decls 51 | ut_parser.o:: CFLAGS += -Wno-switch 52 | ut_vm.o:: CFLAGS += -Wno-switch 53 | 54 | # 55 | # Ignore spurious warnings about __STRICT_ANSI__ and YYENABLE_NLS in code 56 | # generated by bison 2.4.1 (EL6) or bison 2.3 (SLES11). Fixed in 2.4.2. 57 | # 58 | ut_grammar.o:: CFLAGS += -Wno-undef 59 | 60 | ut_lex.c: ut_lex.l ut_grammar.h 61 | $(FLEX) --prefix=yyut -o $@ ut_lex.l 62 | 63 | # 64 | # Prevent multiple invocations of bison being run in parallel, since the 65 | # one invocation will produce both .c. and .h. See "Introduction to Pattern 66 | # Rules" in the gmake manual ("If a pattern rule has multiple targets, make 67 | # knows that the rule's recipe is responsible for making all of the targets.") 68 | # 69 | %_grammar.c %_grammar.h: %_grammar.y 70 | $(BISON) -d -v -Werror --name-prefix=yyut \ 71 | --report-file=ut_grammar.output -o ut_grammar.c ut_grammar.y 72 | -------------------------------------------------------------------------------- /lib/libutrace/utrace_impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UTRACE_IMPL_H 18 | #define _UTRACE_IMPL_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | #ifndef YYSTYPE 39 | #include 40 | #define YYSTYPE YYSTYPE 41 | #endif 42 | 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | typedef struct ut_ecb { 52 | struct ut_ecb *utecb_prev; 53 | struct ut_ecb *utecb_next; 54 | uint64_t utecb_vars; 55 | uint64_t *utecb_code; 56 | uint32_t utecb_clen; 57 | uint16_t utecb_errors; 58 | uint16_t utecb_drops; 59 | } ut_ecb_t; 60 | 61 | struct utrace_request { 62 | void *req_buf; 63 | size_t req_len; 64 | }; 65 | 66 | struct utrace_handle { 67 | int uth_dbg; 68 | ut_obj_t *uth_obj; 69 | utrace_request_t *uth_req; 70 | }; 71 | 72 | enum utrace_event { 73 | EVENT_UNKNOWN = -1 74 | }; 75 | 76 | extern void utrace_func_empty(ut_pcb_t *, ut_node_t *); 77 | extern void utrace_func_nonempty(ut_pcb_t *, ut_node_t *); 78 | extern void utrace_func_prof(ut_pcb_t *, ut_node_t *); 79 | 80 | extern utrace_print_f *UT_printf __attribute__((format(printf, 2, 0))); 81 | extern utrace_trace_f *UT_tracef __attribute__((format(printf, 3, 0))); 82 | 83 | extern FILE *UT_stdout; 84 | extern __thread uint8_t UT_depth; 85 | extern __thread ut_buf_t *UT_self; 86 | extern utrace_handle_t UT_ctor; 87 | extern ut_obj_t UT_exec; 88 | extern utrace_prof_ops_t UT_prof; 89 | 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | 94 | #endif /* _UTRACE_IMPL_H */ 95 | -------------------------------------------------------------------------------- /lib/libutrace/ut_open.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | __thread uint8_t UT_depth; 20 | __thread ut_buf_t *UT_self; 21 | utrace_handle_t UT_ctor; 22 | ut_obj_t UT_exec; 23 | 24 | void * 25 | utrace_thread_init(size_t size) 26 | { 27 | if (UT_self == NULL || UT_self->utbuf_size != size) { 28 | utrace_buf_destroy(UT_self); 29 | UT_self = utrace_buf_create(size); 30 | } 31 | return (UT_self); 32 | } 33 | 34 | void 35 | utrace_thread_fini(void) 36 | { 37 | utrace_buf_destroy(UT_self); 38 | UT_self = NULL; 39 | } 40 | 41 | static void 42 | __attribute__((constructor)) 43 | utrace_init(void) 44 | { 45 | utrace_handle_t *uhp = &UT_ctor; 46 | 47 | UT_printf = vfprintf; 48 | UT_tracef = vsnprintf; 49 | UT_stdout = stdout; 50 | 51 | uhp->uth_dbg = getenv("UTRACE_DEBUG") != NULL; 52 | uhp->uth_obj = &UT_exec; 53 | 54 | utrace_obj_init(uhp->uth_obj); 55 | utrace_obj_load(uhp, uhp->uth_obj, "/proc/self/exe"); 56 | utrace_obj_hold(uhp->uth_obj); 57 | 58 | if (getenv("UTRACE_PROBES") != NULL) { 59 | utrace_walk(uhp, utrace_list, stdout); 60 | exit(0); 61 | } 62 | 63 | utrace_thread_init(sysconf(_SC_PAGESIZE)); 64 | utrace_profile(NULL); 65 | } 66 | 67 | static void 68 | __attribute__((destructor)) 69 | utrace_fini(void) 70 | { 71 | (void) yyutlex_destroy(); 72 | utrace_thread_fini(); 73 | utrace_obj_rele(UT_ctor.uth_obj); 74 | } 75 | 76 | utrace_handle_t * 77 | utrace_open_self(void) 78 | { 79 | utrace_handle_t *uhp = vmem_zalloc(vmem_heap, sizeof (*uhp), VM_SLEEP); 80 | 81 | uhp->uth_dbg = getenv("UTRACE_DEBUG") != NULL; 82 | uhp->uth_obj = &UT_exec; 83 | 84 | utrace_obj_hold(uhp->uth_obj); 85 | return (uhp); 86 | } 87 | 88 | void 89 | utrace_close(utrace_handle_t *uhp) 90 | { 91 | if (uhp == NULL) 92 | return; /* simplify caller code */ 93 | 94 | utrace_disable(uhp); 95 | utrace_obj_rele(uhp->uth_obj); 96 | vmem_free(vmem_heap, uhp, sizeof (*uhp)); 97 | } 98 | -------------------------------------------------------------------------------- /lib/libutrace/ut_file.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | static const size_t 20 | utrace_file_align[UT_FILE_SECT_MAX] = { 21 | [UT_FILE_SECT_HDR] = sizeof (uint8_t), 22 | [UT_FILE_SECT_PROBE] = sizeof (uint32_t), 23 | [UT_FILE_SECT_CODE] = sizeof (uint64_t), 24 | [UT_FILE_SECT_STR] = sizeof (char), 25 | }; 26 | 27 | /* 28 | * Calculate the final object file size, allocate a buffer for its content, 29 | * and then relocate the per-section pointers according to their sizes. 30 | * The start of each section is aligned according to utrace_file_align[] above. 31 | */ 32 | void 33 | utrace_file_alloc(ut_file_t *file) 34 | { 35 | ut_file_sect_t sect; 36 | size_t size = 0; 37 | 38 | for (sect = UT_FILE_SECT_HDR; sect < UT_FILE_SECT_MAX; sect++) { 39 | size = P2ROUNDUP(size, utrace_file_align[sect]); 40 | file->utfi_sect[sect].utfs_ptr = (uint8_t *)size; 41 | size += file->utfi_sect[sect].utfs_len; 42 | file->utfi_sect[sect].utfs_len = 0; 43 | } 44 | 45 | file->utfi_data = vmem_zalloc(vmem_heap, size, VM_SLEEP); 46 | file->utfi_size = size; 47 | 48 | for (sect = UT_FILE_SECT_HDR; sect < UT_FILE_SECT_MAX; sect++) 49 | file->utfi_sect[sect].utfs_ptr += (size_t)file->utfi_data; 50 | } 51 | 52 | /* 53 | * Write to the specified section. If utrace_file_alloc() has been called, 54 | * copy in the data; otherwise just increase the size of the section. 55 | */ 56 | size_t 57 | utrace_file_write(ut_file_t *file, 58 | ut_file_sect_t sect, const void *src, size_t len) 59 | { 60 | ut_file_subs_t *sp = &file->utfi_sect[sect]; 61 | size_t off = sp->utfs_ptr - file->utfi_data; 62 | 63 | if (sp->utfs_ptr != NULL) { 64 | bcopy(src, sp->utfs_ptr, len); 65 | sp->utfs_ptr += len; 66 | } 67 | 68 | sp->utfs_len += len; 69 | return (off); 70 | } 71 | 72 | size_t 73 | utrace_file_wroff(const ut_file_t *file, ut_file_sect_t sect) 74 | { 75 | return (file->utfi_sect[sect].utfs_ptr - file->utfi_data); 76 | } 77 | -------------------------------------------------------------------------------- /lib/libustat/ustat_ms.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _USTAT_MS_H 18 | #define _USTAT_MS_H 19 | 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* 27 | * Userland Statistics Microstate Class 28 | * 29 | * This class provides the ability to quantize operations that have microstate 30 | * accounting data into power-of-two buckets, and then display two-dimensional 31 | * analysis of their time distribution, and work distribution by microstate. 32 | * This is a more specialized form of the generic ustat_hg histogram. 33 | */ 34 | 35 | typedef struct ustat_ms { 36 | ustat_named_t usms_nrows; /* number of rows / time buckets */ 37 | ustat_named_t usms_ncols; /* number of columns / microstates */ 38 | ustat_named_t usms_names; /* string array of microstate names */ 39 | ustat_named_t usms_ctons; /* cycle to ns for hrcyctonsm() */ 40 | ustat_named_t usms_stats[1]; /* rows * cols encoded histogram */ 41 | } ustat_ms_t; 42 | 43 | typedef struct ustat_ms_spec { 44 | const char *const *usms_names; /* array of microstate names */ 45 | uint8_t usms_rows; /* number of rows / time buckets */ 46 | uint8_t usms_cols; /* number of cols / microstates */ 47 | uint32_t usms_ctons; /* cycles to nanoseconds */ 48 | } ustat_ms_spec_t; 49 | 50 | extern const ustat_class_t ustat_class_ms; 51 | 52 | extern void ustat_ms_enter(ustat_ms_t *, ustat_ms_spec_t *, const uint64_t *); 53 | extern void ustat_ms_printx(ustat_ms_spec_t *, const uint64_t *, FILE *); 54 | extern void ustat_ms_printv(ustat_ms_spec_t *, const uint64_t *, FILE *); 55 | extern void ustat_ms_print(ustat_ms_t *, FILE *); 56 | extern void ustat_ms_reset(ustat_ms_t *); 57 | 58 | extern const uint64_t *ustat_ms_import(ustat_ms_spec_t *, const void *, size_t); 59 | extern size_t ustat_ms_export(ustat_ms_t *, void *, size_t); 60 | extern void ustat_ms_destroy(ustat_ms_spec_t *); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif /* _USTAT_MS_H */ 67 | -------------------------------------------------------------------------------- /lib/libhrtime/hrtime_arm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * TODO: ARM provides a performance monitoring counter (PMCCNTR) which could be 19 | * used by hrtime. Unfortunately PMCCNTR is not available to user space 20 | * by default (including the stock kernel used by our Armada CPU). If 21 | * hrtime performance on ARM becomes important in the future then we 22 | * should implement a PMCCNTR option, e.g. enabled via the hrtime kmod. 23 | */ 24 | 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | static uint32_t hrtime_clock_mult; /* used to convert clock cycles to ns */ 31 | 32 | 33 | inline uint32_t __attribute__ ((optimize("omit-frame-pointer"))) 34 | gethrcycle_mult(void) 35 | { 36 | return (hrtime_clock_mult); 37 | } 38 | 39 | inline void __attribute__ ((optimize("omit-frame-pointer"))) 40 | sethrcycle_mult(uint32_t mult) 41 | { 42 | hrtime_clock_mult = mult; 43 | } 44 | 45 | /* 46 | * The 32-bit version of hrcyctonsm() may overflow given that 128-bit math is 47 | * not available. However, we don't support the TSC clock source in 32-bit mode 48 | * anyway, and the fallback is clock_gettime() which uses a 1ns timer, i.e. 49 | * cycles == ns, so special-case this to stop potential overflows. 50 | */ 51 | inline uint64_t __attribute__ ((optimize("omit-frame-pointer"))) 52 | hrcyctonsm(uint64_t cycles, uint64_t clock_mult) 53 | { 54 | if (clock_mult == (1ULL << CYC_TO_NS_SCALE)) 55 | return (cycles); 56 | else 57 | return ((cycles * clock_mult) >> CYC_TO_NS_SCALE); 58 | } 59 | 60 | /* 61 | * hrcyctons() converts a cycle value (from gethrcycles()) to the number of 62 | * nanoseconds since an unspecified starting point. 63 | */ 64 | uint64_t __attribute__ ((optimize("omit-frame-pointer"))) 65 | hrcyctons(uint64_t cycles) 66 | { 67 | return (hrcyctonsm(cycles, hrtime_clock_mult)); 68 | } 69 | 70 | /* 71 | * ARM-specific hrtime init function. 72 | */ 73 | void 74 | hrtime_init_cpu(void) 75 | { 76 | } 77 | -------------------------------------------------------------------------------- /lib/libutrace/ut_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * UTrace Test Program 19 | * 20 | * This program compiles the probe program from stdin, and then calls a stack 21 | * of three functions, each with a probe defined-- we then use ut_test.u to 22 | * instrument this sequence and make sure all probes fire, variables trace, etc 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | enum utrace_event { 36 | EV_FOO, 37 | EV_BAR, 38 | EV_BAZ, 39 | }; 40 | 41 | extern int foo(int); 42 | extern int bar(int); 43 | extern int baz(int); 44 | 45 | uint64_t 46 | gethrcycles(void) 47 | { 48 | return (0xc1c1c1c1c1c1c1c1); 49 | } 50 | 51 | uint64_t 52 | gethrtime(void) 53 | { 54 | return (0xd1d1d1d1d1d1d1d1); 55 | } 56 | 57 | int 58 | __attribute__((noinline)) 59 | baz(int x) 60 | { 61 | errno = 123; 62 | 63 | utrace(EV_BAZ, "x=%d", x); 64 | 65 | (void) printf("baz(%d)\n", x); 66 | 67 | return (x + 1); 68 | } 69 | 70 | int 71 | __attribute__((noinline)) 72 | bar(int x) 73 | { 74 | utrace(EV_BAR, "x=%d", x); 75 | x = baz(x + 1); 76 | return (x + 1); 77 | } 78 | 79 | int 80 | __attribute__((noinline)) 81 | foo(int x) 82 | { 83 | utrace(EV_FOO, "x=%d", x); 84 | x = bar(x + 1); 85 | return (x + 1); 86 | } 87 | 88 | int 89 | main(int argc, char *argv[]) 90 | { 91 | utrace_handle_t *h; 92 | utrace_request_t *r; 93 | 94 | cpu_set_t *cpus; 95 | size_t size; 96 | int rv; 97 | int x = 1; 98 | 99 | h = utrace_open_self(); 100 | r = utrace_fcompile(h, stdin); 101 | 102 | if (r != NULL) 103 | utrace_enable(h, r); 104 | 105 | size = CPU_ALLOC_SIZE(sysconf(_SC_NPROCESSORS_CONF)); 106 | cpus = alloca(size); 107 | CPU_ZERO_S(size, cpus); 108 | CPU_SET_S(0, size, cpus); 109 | pthread_setaffinity_np(pthread_self(), size, cpus); 110 | 111 | if (argc > 1) { 112 | x = atoi(argv[1]); 113 | while (--x > 0) 114 | bar(x); 115 | } 116 | 117 | rv = foo(1); 118 | 119 | utrace_close(h); 120 | return (rv); 121 | } 122 | -------------------------------------------------------------------------------- /lib/libutrace/ut_subr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | utrace_print_f *UT_printf; 20 | utrace_trace_f *UT_tracef; 21 | FILE *UT_stdout; 22 | 23 | void 24 | utrace_redir_print(utrace_print_f *func, FILE *file) 25 | { 26 | UT_printf = func; 27 | UT_stdout = file; 28 | } 29 | 30 | void 31 | utrace_redir_trace(utrace_trace_f *func) 32 | { 33 | UT_tracef = func; 34 | } 35 | 36 | ssize_t 37 | __attribute__((format(printf, 3, 0))) 38 | utrace_vtracef(char *buf, size_t len, const char *format, va_list ap) 39 | { 40 | return (UT_tracef(buf, len, format, ap)); 41 | } 42 | 43 | void 44 | __attribute__((format(printf, 2, 0))) 45 | utrace_vprintf(FILE *fp, const char *format, va_list ap) 46 | { 47 | (void) UT_printf(fp, format, ap); 48 | } 49 | 50 | void 51 | __attribute__((format(printf, 2, 3))) 52 | utrace_printf(FILE *fp, const char *format, ...) 53 | { 54 | va_list ap; 55 | 56 | va_start(ap, format); 57 | (void) UT_printf(fp, format, ap); 58 | va_end(ap); 59 | } 60 | 61 | void 62 | __attribute__((format(printf, 1, 2))) 63 | utrace_dprintf(const char *format, ...) 64 | { 65 | if (yyutdebug) { 66 | va_list ap; 67 | va_start(ap, format); 68 | (void) vfprintf(stderr, format, ap); 69 | va_end(ap); 70 | } 71 | } 72 | 73 | int 74 | __attribute__((format(printf, 3, 0))) 75 | utrace_verror(utrace_handle_t *uhp, int err, const char *format, va_list ap) 76 | { 77 | (void) fprintf(stderr, "utrace error: "); 78 | (void) vfprintf(stderr, format, ap); 79 | (void) fprintf(stderr, "\n"); 80 | 81 | errno = err; 82 | return (-1); 83 | } 84 | 85 | int 86 | __attribute__((format(printf, 3, 4))) 87 | utrace_error(utrace_handle_t *uhp, int err, const char *format, ...) 88 | { 89 | va_list ap; 90 | 91 | va_start(ap, format); 92 | err = utrace_verror(uhp, err, format, ap); 93 | va_end(ap); 94 | 95 | return (err); 96 | } 97 | 98 | void * 99 | __attribute__((format(printf, 3, 4))) 100 | utrace_null(utrace_handle_t *uhp, int err, const char *format, ...) 101 | { 102 | va_list ap; 103 | 104 | va_start(ap, format); 105 | (void) utrace_verror(uhp, err, format, ap); 106 | va_end(ap); 107 | 108 | return (NULL); 109 | } 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DSSD Linux Developer Pro C Toolkit 2 | 3 | ## Overview 4 | The DSSD Linux `Pro C Toolkit` is a set of C programming libraries and 5 | utilities that were developed in the course of building the DSSD NVMe 6 | storage array datapath, and were essential in achieving the speed and 7 | flexibility of our implementation (>10M IOPS, <100us avg latency, and a 8 | full-featured object store supporting file, block and key-value interfaces 9 | in only 100K lines of code). 10 | 11 | During the course of building DSSD, we felt that some of our low-level C 12 | programming primitives were so generally useful for C coding on Linux that 13 | they merited being designed as standalone, separate libraries and tools. We 14 | share those components here as open-source in the hope that other projects 15 | may benefit from their design ideas and/or implementation. 16 | 17 | ## Components 18 | The components currently provided by the toolkit are: 19 | 20 | * libbson - bson and json encoder and decoder 21 | * libhrtime - userland timestamp counter access 22 | * libtree - LLRB tree data structure library 23 | * libucore - userland core dump facility for long-running daemon processes 24 | * libunuma - userland programming API for NUMA and hugetlbfs 25 | * libustat - userland statistics library for publication and subscription 26 | * libutrace - userland sub-microsecond tracing and instrumentation engine 27 | * libvmem - userland virtual memory allocator 28 | * libvmem_malloc - libvmem interposition library for malloc and free 29 | * qat - regression test execution engine, compatible with Jenkins 30 | * ustat - userland statistics live and post-mortem query utility 31 | 32 | ## Interfaces 33 | The public interfaces for each library are found in lib*name*/*name*.h (for 34 | example, libvmem/vmem.h). The interfaces should be relatively self- 35 | explanatory once you are familiar with the code. Where applicable, large 36 | block comments are found at the top of the source files with design and 37 | interface documentation. If you begin using one of the provided libraries 38 | extensively, feel free to contribute Doxygen support to this project. 39 | 40 | ## Makefiles 41 | The Makefiles provided for this project are a very simple skeleton just to 42 | show how the source is meant to be built. They do not constitute a full 43 | implementation of configuring and building a set of shipping libraries. 44 | These components are meant to integrated directly with your build system, 45 | which we assume is using its own set of Makefiles and Make conventions. 46 | 47 | ## Authors 48 | The components in this toolkit were written and designed by 49 | [Mike Shapiro](https://en.wikipedia.org/wiki/Mike_Shapiro_(programmer)) 50 | (libhrtime, libucore, libustat, libutrace, qat, ustat), 51 | [Jeff Bonwick](https://en.wikipedia.org/wiki/Jeff_Bonwick) 52 | (libbson, libtree, libvmem, libvmem_malloc), 53 | and Simon Barrett (libunuma, libhrtime, libustat). 54 | 55 | ## License 56 | The DSSD `Pro C Toolkit` project is licensed to you under the Apache License, 57 | Version 2.0. Please refer to the LICENSE file for additional information. 58 | -------------------------------------------------------------------------------- /lib/libutrace/ut_buf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | ut_buf_t * 20 | utrace_buf_create(size_t size) 21 | { 22 | ut_buf_t *bp = vmem_alloc(vmem_heap, sizeof (*bp), VM_SLEEP); 23 | 24 | bp->utbuf_base = vmem_alloc(vmem_heap, size, VM_SLEEP); 25 | bp->utbuf_bend = bp->utbuf_base + size; 26 | bp->utbuf_size = size; 27 | bp->utbuf_free = size; 28 | bp->utbuf_rptr = bp->utbuf_base; 29 | bp->utbuf_wptr = bp->utbuf_base; 30 | 31 | return (bp); 32 | } 33 | 34 | void 35 | utrace_buf_destroy(ut_buf_t *bp) 36 | { 37 | if (bp != NULL) { 38 | vmem_free(vmem_heap, bp->utbuf_base, bp->utbuf_size); 39 | vmem_free(vmem_heap, bp, sizeof (*bp)); 40 | } 41 | } 42 | 43 | /* 44 | * Write a portion of the buffer by copying data from 'src' to utbuf_wptr, 45 | * wrapping the content around to the top of the buffer if necessary. 46 | * The content will be automatically cropped at utbuf_rptr, such that 47 | * we do not overwrite data that has yet to be consumed or erased. 48 | */ 49 | void 50 | utrace_buf_write(ut_buf_t *bp, const void *src, size_t len) 51 | { 52 | const uint8_t *src1, *src2; 53 | size_t len1, len2; 54 | 55 | if (len > bp->utbuf_size) 56 | len = bp->utbuf_size; 57 | 58 | src1 = src; 59 | len1 = len; 60 | 61 | if (len1 > (size_t)(bp->utbuf_bend - bp->utbuf_wptr)) 62 | len1 = (size_t)(bp->utbuf_bend - bp->utbuf_wptr); 63 | 64 | if (len1 != 0) 65 | bcopy(src1, bp->utbuf_wptr, len1); 66 | 67 | src2 = src1 + len1; 68 | len2 = len - len1; 69 | 70 | if (len2 != 0) 71 | bcopy(src2, bp->utbuf_base, len2); 72 | 73 | if (len2 != 0) 74 | bp->utbuf_wptr = bp->utbuf_base + len2; 75 | else if (len1 != 0) 76 | bp->utbuf_wptr = bp->utbuf_wptr + len1; 77 | 78 | if (bp->utbuf_free != 0) 79 | bp->utbuf_free -= len; 80 | } 81 | 82 | /* 83 | * Erase a portion of the buffer (making more space free for writing) by 84 | * moving utbuf_rptr such that at least 'len' bytes are considered free. 85 | */ 86 | void 87 | utrace_buf_erase(ut_buf_t *bp, size_t len) 88 | { 89 | if (len > bp->utbuf_size - bp->utbuf_free) 90 | len = bp->utbuf_size - bp->utbuf_free; 91 | 92 | if (len > (size_t)(bp->utbuf_bend - bp->utbuf_rptr)) 93 | bp->utbuf_rptr = bp->utbuf_base + len - 94 | (size_t)(bp->utbuf_bend - bp->utbuf_rptr); 95 | else 96 | bp->utbuf_rptr = bp->utbuf_rptr + len; 97 | 98 | bp->utbuf_free += len; 99 | } 100 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_unuma.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | 21 | /* 22 | * ============================================================================ 23 | * unuma operations 24 | * ============================================================================ 25 | */ 26 | 27 | static void * 28 | vmem_unuma_xalloc(vmem_t *vm, size_t size, size_t align, size_t phase, int flag) 29 | { 30 | int saved_errno = errno; 31 | unuma_pgt_t pgt; 32 | void *vaddr; 33 | int node; 34 | 35 | if (size == 0) 36 | return (NULL); 37 | 38 | if (!IS_P2ALIGNED(size | align | phase, vm->vm_q) || !IS_P2(align)) 39 | vmem_panic_xalloc(vm, size, align, phase, flag, "bad args"); 40 | 41 | /* 42 | * Find the node and pgt for the passed vm so the new allocation has the 43 | * same attributes. 44 | */ 45 | if (vmem_get_numa(vm, &node, &pgt) != 0) 46 | return (NULL); 47 | 48 | if ((align | phase) == 0) 49 | align = vm->vm_q; 50 | 51 | vaddr = (phase >= align) ? (void *)(uintptr_t)phase : NULL; 52 | vaddr = unuma_alloc(vaddr, size, align, pgt, node); 53 | 54 | if (vaddr == MAP_FAILED) { 55 | errno = saved_errno; 56 | return (vmem_xalloc_sleep(vm, size, align, phase, flag)); 57 | } 58 | 59 | ASSERT(P2PHASE((uintptr_t)vaddr, align) == phase); 60 | 61 | errno = saved_errno; 62 | return (vaddr); 63 | } 64 | 65 | static void 66 | vmem_unuma_free(vmem_t *vm, void *addr, size_t size) 67 | { 68 | int saved_errno = errno; 69 | 70 | if (addr == NULL) 71 | return; 72 | 73 | (void) unuma_free(addr, size); 74 | 75 | if (vm->vm_waiters) 76 | vmem_free_wakeup(vm); 77 | 78 | errno = saved_errno; 79 | } 80 | 81 | static size_t 82 | vmem_unuma_walk(vmem_t *vm, vmem_walk_cb *func, void *arg, int w) 83 | { 84 | return (0); 85 | } 86 | 87 | static void 88 | vmem_unuma_vacate(vmem_t *vm, int v) 89 | { 90 | } 91 | 92 | static int 93 | vmem_unuma_init(vmem_t *vm) 94 | { 95 | return (0); 96 | } 97 | 98 | static void 99 | vmem_unuma_fini(vmem_t *vm) 100 | { 101 | } 102 | 103 | const vmem_ops_t vmem_unuma_ops = { 104 | .vop_xalloc = vmem_unuma_xalloc, 105 | .vop_free = vmem_unuma_free, 106 | .vop_debug = NULL, 107 | .vop_add = NULL, 108 | .vop_remove = NULL, 109 | .vop_walk = vmem_unuma_walk, 110 | .vop_vacate = vmem_unuma_vacate, 111 | .vop_init = vmem_unuma_init, 112 | .vop_fini = vmem_unuma_fini, 113 | .vop_name = "unuma", 114 | .vop_attr = VMEM_OP_BASE 115 | }; 116 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_cd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | /* 20 | * ============================================================================ 21 | * Construct/destruct operations 22 | * ============================================================================ 23 | */ 24 | static void * 25 | vmem_cd_default_construct(const vmem_t *vm, void *addr, size_t size, int flag) 26 | { 27 | return (addr); 28 | } 29 | 30 | static void 31 | vmem_cd_default_destruct(const vmem_t *vm, void *addr, size_t size) 32 | { 33 | } 34 | 35 | static void * 36 | vmem_cd_xalloc(vmem_t *vm, size_t size, size_t align, size_t phase, int flag) 37 | { 38 | void *addr; 39 | 40 | addr = vmem_xalloc(vm->vm_source, size, align, phase, flag); 41 | 42 | if (addr == NULL) 43 | return (NULL); 44 | 45 | if (vm->vm_construct(vm->vm_source, addr, size, flag) == NULL) { 46 | vmem_free(vm->vm_source, addr, size); 47 | return (NULL); 48 | } 49 | 50 | return (addr); 51 | } 52 | 53 | static void 54 | vmem_cd_free(vmem_t *vm, void *addr, size_t size) 55 | { 56 | if (addr == NULL) 57 | return; 58 | 59 | vm->vm_destruct(vm->vm_source, addr, size); 60 | 61 | vmem_free(vm->vm_source, addr, size); 62 | } 63 | 64 | static void 65 | vmem_cd_add(vmem_t *vm, void *addr, size_t size) 66 | { 67 | vmem_add(vm->vm_source, addr, size); 68 | } 69 | 70 | static void 71 | vmem_cd_remove(vmem_t *vm, void *addr, size_t size) 72 | { 73 | vmem_remove(vm->vm_source, addr, size); 74 | } 75 | 76 | static size_t 77 | vmem_cd_walk(vmem_t *vm, vmem_walk_cb *func, void *arg, int w) 78 | { 79 | return (vmem_walk(vm->vm_source, func, arg, w)); 80 | } 81 | 82 | static void 83 | vmem_cd_vacate(vmem_t *vm, int v) 84 | { 85 | if (v & VMEM_VACATE_SELF_ONLY) 86 | return; 87 | 88 | vmem_vacate(vm->vm_source, v); 89 | } 90 | 91 | static int 92 | vmem_cd_init(vmem_t *vm) 93 | { 94 | if (vm->vm_construct == NULL) 95 | vm->vm_construct = vmem_cd_default_construct; 96 | 97 | if (vm->vm_destruct == NULL) 98 | vm->vm_destruct = vmem_cd_default_destruct; 99 | 100 | return (0); 101 | } 102 | 103 | static void 104 | vmem_cd_fini(vmem_t *vm) 105 | { 106 | } 107 | 108 | const vmem_ops_t vmem_cd_ops = { 109 | .vop_xalloc = vmem_cd_xalloc, 110 | .vop_free = vmem_cd_free, 111 | .vop_debug = NULL, 112 | .vop_add = vmem_cd_add, 113 | .vop_remove = vmem_cd_remove, 114 | .vop_walk = vmem_cd_walk, 115 | .vop_vacate = vmem_cd_vacate, 116 | .vop_init = vmem_cd_init, 117 | .vop_fini = vmem_cd_fini, 118 | .vop_name = "cd", 119 | .vop_attr = VMEM_OP_FILTER 120 | }; 121 | -------------------------------------------------------------------------------- /lib/libustat/ustat_hg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _USTAT_HG_H 18 | #define _USTAT_HG_H 19 | 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* 27 | * Userland Statistics Histogram Class 28 | * 29 | * This class provides the ability to quantize a set of input values such as 30 | * read or write sizes or offsets into power-of-two buckets and then display 31 | * these values as a histogram, similar to the effect of DTrace aggregations. 32 | */ 33 | 34 | /* 35 | * ushg_vtype, which is passed as the uarg to ustat_insert(), dicates how the 36 | * histogram row values should be printed. For example: 37 | * 38 | * USTAT_TYPE_DELTA: print as nanosecond values using ushg_ctons to convert 39 | * the raw cycle values in the bins to nanoseconds. 40 | * USTAT_TYPE_SIZE: print using size units 41 | * USTAT_TYPE_UINT64: print as a uint64. 42 | * 43 | * All other types are invalid. 44 | */ 45 | typedef struct ustat_hg { 46 | ustat_named_t ushg_vtype; 47 | ustat_named_t ushg_ctons; 48 | ustat_named_t ushg_bins[65]; 49 | } ustat_hg_t; 50 | 51 | typedef struct ustat_hg_plot { 52 | uint32_t ushp_bins[65]; 53 | uint32_t ushp_lobin; 54 | uint32_t ushp_hibin; 55 | double ushp_unit; 56 | uint64_t ushp_min; 57 | uint64_t ushp_max; 58 | } ustat_hg_plot_t; 59 | 60 | 61 | typedef enum { 62 | USHM_BIN_INDICIES, 63 | USHM_BIN_COUNTS, 64 | USHM_MAX, 65 | } ustat_hg_multi_type_t; 66 | 67 | typedef struct ustat_hg_multi { 68 | ustat_hg_multi_type_t ushm_type; 69 | uint32_t ushm_plotc; 70 | ustat_hg_plot_t *ushm_hp; 71 | ustat_hg_t **ushm_hg; 72 | } ustat_hg_multi_t; 73 | 74 | extern const ustat_class_t ustat_class_hg; 75 | 76 | extern int ustat_hg_bin64(uint64_t); 77 | extern void ustat_hg_enter(ustat_hg_t *, uint64_t); 78 | extern void ustat_hg_atomic_enter(ustat_hg_t *, uint64_t); 79 | extern void ustat_hg_plot(ustat_hg_t *, ustat_hg_plot_t *, uint32_t); 80 | extern void ustat_hg_reset(ustat_hg_t *); 81 | extern void ustat_hg_fprint_unit(FILE *, const char *, ustat_hg_t *, 82 | const ustat_unit_t *); 83 | extern void ustat_hg_fprint_cyctotime(FILE *, const char *, ustat_hg_t *, 84 | uint64_t); 85 | 86 | extern void ustat_hgm_enter(ustat_hg_multi_t *, uint64_t); 87 | extern void ustat_hgm_fprint_unit(FILE *, const char *, const char *, 88 | const char *, ustat_hg_multi_t *); 89 | extern void ustat_hgm_create(ustat_handle_t *, ustat_hg_multi_t *, uint32_t, 90 | uint32_t, ustat_hg_multi_type_t, const char *); 91 | extern void ustat_hgm_destroy(ustat_hg_multi_t *); 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif /* _USTAT_HG_H */ 98 | -------------------------------------------------------------------------------- /lib/libtree/tree.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _TREE_H 18 | #define _TREE_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #define TREE_NODE_BLACK (0UL) 29 | #define TREE_NODE_RED (1UL) 30 | #define TREE_NODE_RIGHT (~TREE_NODE_RED) 31 | 32 | typedef int tree_compare_f(const void *, const void *); 33 | typedef void tree_walk_f(void *, void *); 34 | 35 | typedef struct tree_node { 36 | uintptr_t n_left; 37 | uintptr_t n_right_red; 38 | } tree_node_t; 39 | 40 | typedef struct tree { 41 | tree_node_t *t_root; 42 | tree_compare_f *t_cmp; 43 | size_t t_off; 44 | } tree_t; 45 | 46 | /* 47 | * Inline-able lookup. lookf should be declared in the same file as cmpf 48 | * so that the comparison can be inlined. See tree_test.c for an example. 49 | */ 50 | #define TREE_LOOKUP_FUNC(lookf, cmpf, str, field) \ 51 | str * \ 52 | lookf(const tree_t *t, const str *x) \ 53 | { \ 54 | tree_node_t *n = t->t_root; \ 55 | while (n != NULL) { \ 56 | void *f = (uint8_t *)n - offsetof(str, field); \ 57 | int cmp = cmpf(x, f); \ 58 | if (cmp == 0) \ 59 | return (f); \ 60 | n = (tree_node_t *)(cmp < 0 ? \ 61 | n->n_left : n->n_right_red & TREE_NODE_RIGHT); \ 62 | } \ 63 | return (NULL); \ 64 | } 65 | 66 | extern void tree_init(tree_t *t, tree_compare_f *cmp, size_t off); 67 | extern void tree_fini(tree_t *t); 68 | extern void *tree_min(const tree_t *t); 69 | extern void *tree_max(const tree_t *t); 70 | extern void *tree_root(const tree_t *t); 71 | extern void *tree_lookup(const tree_t *t, const void *data); 72 | extern void *tree_prev(const tree_t *t, const void *data); 73 | extern void *tree_next(const tree_t *t, const void *data); 74 | extern void *tree_locate(const tree_t *t, const void *data, void **, void **); 75 | extern void *tree_try_insert(tree_t *t, void *data); 76 | extern void tree_insert(tree_t *t, void *data); 77 | extern void *tree_delete_min(tree_t *t); 78 | extern void *tree_delete_max(tree_t *t); 79 | extern void *tree_try_delete(tree_t *t, void *data); 80 | extern void tree_delete(tree_t *t, void *data); 81 | extern void tree_teardown(tree_t *t, tree_walk_f *destructor, void *private); 82 | extern int tree_empty(const tree_t *t); 83 | extern size_t tree_nodes(const tree_t *t); 84 | extern void tree_walk(const tree_t *t, tree_walk_f *func, void *private); 85 | extern int tree_valid(const tree_t *t); 86 | extern void tree_draw(const tree_t *t, int flat); 87 | extern void tree_test(void); 88 | extern void tree_move(tree_t *, tree_t *); 89 | 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | 94 | #endif /* _TREE_H */ 95 | -------------------------------------------------------------------------------- /lib/libunuma/unuma.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UNUMA_H 18 | #define UNUMA_H 19 | 20 | #include 21 | #include 22 | #include /* MAP_FAILED */ 23 | 24 | /* 25 | * Maximum number of NUMA nodes supported. 26 | * 27 | * Do not raise this value unless absolutely necessary - code external to 28 | * libunuma uses this in ways in which every bit counts. 29 | */ 30 | #define UNUMA_MAX_NODES (8) 31 | #define UNUMA_MAX_SHIFT (3) 32 | 33 | /* 34 | * Default mountpoints for the corresponding hugetlbfs page sizes. 35 | * These can be overridden by the user. 36 | */ 37 | #if !defined(UNUMA_HUGETLBFS_2M) 38 | #define UNUMA_HUGETLBFS_2M NULL 39 | #endif 40 | 41 | #if !defined(UNUMA_HUGETLBFS_1G) 42 | #define UNUMA_HUGETLBFS_1G NULL 43 | #endif 44 | 45 | /* 46 | * Controls whether libunuma is allowed to scan for hugetlbfs mountpoints and 47 | * use any that match versus only using the default mountpoints, if any, above. 48 | */ 49 | #if !defined(UNUMA_HUGETLBFS_SCAN) 50 | #define UNUMA_HUGETLBFS_SCAN 1 51 | #endif 52 | 53 | 54 | /* 55 | * NUMA node page types. 56 | * UNUMA_PGT_{SMALL,LARGE,HUGE} should be used whenever possible for portability 57 | */ 58 | typedef enum unuma_pgt { 59 | #if defined(__x86_64__) 60 | UNUMA_PGT_4K, 61 | UNUMA_PGT_2M, 62 | UNUMA_PGT_1G, 63 | UNUMA_PGT_MAX, 64 | 65 | UNUMA_PGT_SMALL = UNUMA_PGT_4K, 66 | UNUMA_PGT_LARGE = UNUMA_PGT_2M, 67 | UNUMA_PGT_HUGE = UNUMA_PGT_1G, 68 | #elif defined(__i386__) || defined(__arm__) 69 | /* XXX add support for ARM large (64K) pages */ 70 | UNUMA_PGT_4K, 71 | UNUMA_PGT_MAX, 72 | 73 | UNUMA_PGT_SMALL = UNUMA_PGT_4K, 74 | UNUMA_PGT_LARGE = UNUMA_PGT_4K, 75 | UNUMA_PGT_HUGE = UNUMA_PGT_4K, 76 | #else 77 | #error "unknown arch" 78 | #endif 79 | } unuma_pgt_t; 80 | 81 | 82 | extern size_t unuma_page_size(unuma_pgt_t); 83 | extern unuma_pgt_t unuma_page_type(uint64_t); 84 | 85 | extern int unuma_get_node(void); 86 | extern int unuma_get_nnodes(void); 87 | extern bool unuma_is_node_present(int); 88 | extern uint64_t unuma_node_physmem(int); 89 | extern int64_t unuma_node_pages(unuma_pgt_t, int); 90 | extern int64_t unuma_node_freepages(unuma_pgt_t, int); 91 | 92 | extern bool unuma_get_pgt_fallback(void); 93 | extern bool unuma_set_pgt_fallback(bool); 94 | extern bool unuma_is_broken(void); 95 | 96 | extern size_t unuma_roundup(size_t, unuma_pgt_t); 97 | extern void *unuma_alloc(void *, size_t, size_t, unuma_pgt_t, int); 98 | extern int unuma_free(void *, size_t); 99 | 100 | extern int unuma_vtop(const void *, uint64_t *); 101 | extern int unuma_vtonode(const void *); 102 | extern int unuma_ptonode(uint64_t); 103 | 104 | #endif // UNUMA_H 105 | -------------------------------------------------------------------------------- /lib/libucore/nt_prpsinfo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | ssize_t 23 | nt_prpsinfo_size(NElf_Word type, int fd, off_t off, pid_t tid) 24 | { 25 | if (tid != ucore_gettid()) 26 | return (0); /* only for the main thread */ 27 | 28 | return (ucore_note_size(type, 29 | "CORE", sizeof (struct elf_prpsinfo))); 30 | } 31 | 32 | static int 33 | nt_prpsinfo_stat(size_t argc, char *argv[], void *data) 34 | { 35 | struct elf_prpsinfo *p = data; 36 | const char states[] = "RSDTZW"; 37 | 38 | const char *sp; 39 | char sname; 40 | long nicev; 41 | 42 | (void) sscanf(argv[2], "%c", &sname); 43 | sp = strchr(states, sname); 44 | (void) sscanf(argv[18], "%ld", &nicev); 45 | 46 | p->pr_state = sp ? (char)(sp - states) : -1; 47 | p->pr_sname = sname; 48 | p->pr_zomb = sname == 'Z'; 49 | p->pr_nice = (char)nicev; 50 | 51 | (void) sscanf(argv[8], "%lu", &p->pr_flag); 52 | (void) sscanf(argv[0], "%d", &p->pr_pid); 53 | (void) sscanf(argv[3], "%d", &p->pr_ppid); 54 | (void) sscanf(argv[4], "%d", &p->pr_pgrp); 55 | (void) sscanf(argv[5], "%d", &p->pr_sid); 56 | 57 | return (0); 58 | } 59 | 60 | static int 61 | nt_prpsinfo_uids(size_t argc, char *argv[], void *data) 62 | { 63 | struct elf_prpsinfo *p = data; 64 | 65 | if (argc >= 5 && strcmp(argv[0], "Uid:") == 0) 66 | (void) sscanf(argv[1], sizeof (p->pr_uid) == 2 ? "%hd" : "%d", 67 | &p->pr_uid); 68 | else if (argc >= 5 && strcmp(argv[1], "Gid:") == 0) 69 | (void) sscanf(argv[1], sizeof (p->pr_gid) == 2 ? "%hd" : "%d", 70 | &p->pr_gid); 71 | 72 | return (0); 73 | } 74 | 75 | ssize_t 76 | nt_prpsinfo_dump(NElf_Word type, int fd, off_t off, pid_t tid) 77 | { 78 | struct elf_prpsinfo p; 79 | ssize_t i, len; 80 | 81 | if (tid != ucore_gettid()) 82 | return (0); /* only for the main thread */ 83 | 84 | bzero(&p, sizeof (p)); 85 | 86 | (void) ucore_parse(nt_prpsinfo_stat, &p, 87 | "/proc/%d/stat", ucore_getpid()); 88 | 89 | (void) ucore_parse(nt_prpsinfo_uids, &p, 90 | "/proc/%d/status", ucore_getpid()); 91 | 92 | (void) ucore_slurp(UCORE_S_STR, p.pr_fname, 93 | sizeof (p.pr_fname), "/proc/%d/comm", ucore_getpid()); 94 | 95 | len = ucore_slurp(UCORE_S_BIN, p.pr_psargs, 96 | sizeof (p.pr_psargs) - 1, "/proc/%d/cmdline", ucore_getpid()); 97 | 98 | /* 99 | * This loop has an off-by-one error: the final \0 read from cmdline 100 | * should be left as-is but is instead blindly turned into a space. 101 | * This mimics the observed behavior of Linux-generated core files. 102 | */ 103 | for (i = 0; i < len; i++) 104 | if (p.pr_psargs[i] == '\0') 105 | p.pr_psargs[i] = ' '; 106 | 107 | return (ucore_note_dump(fd, off, type, "CORE", &p, sizeof (p))); 108 | } 109 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_mmap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | /* 23 | * ============================================================================ 24 | * mmap operations 25 | * ============================================================================ 26 | */ 27 | static void * 28 | vmem_mmap_xalloc(vmem_t *vm, size_t size, size_t align, size_t phase, int flag) 29 | { 30 | int saved_errno = errno; 31 | void *addr, *vaddr, *addr_end, *vaddr_end; 32 | size_t vsize; 33 | 34 | if (size == 0) 35 | return (NULL); 36 | 37 | if (!IS_P2ALIGNED(size | align | phase, vm->vm_q) || !IS_P2(align)) 38 | vmem_panic_xalloc(vm, size, align, phase, flag, "bad args"); 39 | 40 | if ((align | phase) == 0) 41 | align = vm->vm_q; 42 | 43 | vsize = (align <= vm->vm_q) ? size : P2ROUNDUP(size + align, align); 44 | vaddr = (phase >= align) ? (void *)(uintptr_t)phase : NULL; 45 | vaddr = mmap(vaddr, vsize, PROT_READ | PROT_WRITE, 46 | MAP_PRIVATE | MAP_ANON | (phase >= align ? MAP_FIXED : 0), -1, 0); 47 | vaddr_end = vaddr + vsize; 48 | 49 | if (vaddr == MAP_FAILED) { 50 | errno = saved_errno; 51 | return (vmem_xalloc_sleep(vm, size, align, phase, flag)); 52 | } 53 | 54 | align = (phase >= align) ? 0 : align; 55 | addr = (void *)P2PHASEUP((uintptr_t)vaddr, align, phase); 56 | addr_end = addr + size; 57 | ASSERT(addr >= vaddr && addr_end <= vaddr_end); 58 | if (vaddr < addr) 59 | (void) munmap(vaddr, addr - vaddr); 60 | if (vaddr_end > addr_end) 61 | (void) munmap(addr_end, vaddr_end - addr_end); 62 | ASSERT(P2PHASE((uintptr_t)addr, align) == phase); 63 | 64 | errno = saved_errno; 65 | 66 | return (addr); 67 | } 68 | 69 | static void 70 | vmem_mmap_free(vmem_t *vm, void *addr, size_t size) 71 | { 72 | int saved_errno = errno; 73 | 74 | if (addr == NULL) 75 | return; 76 | 77 | (void) munmap(addr, P2ROUNDUP(size, vm->vm_q)); 78 | 79 | if (vm->vm_waiters) 80 | vmem_free_wakeup(vm); 81 | 82 | errno = saved_errno; 83 | } 84 | 85 | static size_t 86 | vmem_mmap_walk(vmem_t *vm, vmem_walk_cb *func, void *arg, int w) 87 | { 88 | return (0); 89 | } 90 | 91 | static void 92 | vmem_mmap_vacate(vmem_t *vm, int v) 93 | { 94 | } 95 | 96 | static int 97 | vmem_mmap_init(vmem_t *vm) 98 | { 99 | return (0); 100 | } 101 | 102 | static void 103 | vmem_mmap_fini(vmem_t *vm) 104 | { 105 | } 106 | 107 | const vmem_ops_t vmem_mmap_ops = { 108 | .vop_xalloc = vmem_mmap_xalloc, 109 | .vop_free = vmem_mmap_free, 110 | .vop_debug = NULL, 111 | .vop_add = NULL, 112 | .vop_remove = NULL, 113 | .vop_walk = vmem_mmap_walk, 114 | .vop_vacate = vmem_mmap_vacate, 115 | .vop_init = vmem_mmap_init, 116 | .vop_fini = vmem_mmap_fini, 117 | .vop_name = "mmap", 118 | .vop_attr = VMEM_OP_BASE 119 | }; 120 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_verbose.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | /* 20 | * ============================================================================ 21 | * Verbose operations. 22 | * 23 | * This filter arena simply reports every operation with vmem_printf(). 24 | * It is provided both as an example of how to write a simple filter, 25 | * and as an occasionally useful debugging tool. Verbosity can be 26 | * added to any arena by saying "vm = vmem_push(vm, &vmem_verbose_ops);". 27 | * ============================================================================ 28 | */ 29 | static void * 30 | vmem_verbose_xalloc(vmem_t *vm, size_t size, size_t align, size_t phase, 31 | int flag) 32 | { 33 | void *addr = vmem_xalloc(vm->vm_source, size, align, phase, flag); 34 | 35 | vmem_printf("vmem_xalloc(%s, %#zx, %#zx, %#zx, %#x) = %p\n", 36 | vmem_name(vm), size, align, phase, flag, addr); 37 | 38 | return (addr); 39 | } 40 | 41 | static void 42 | vmem_verbose_free(vmem_t *vm, void *addr, size_t size) 43 | { 44 | vmem_printf("vmem_free(%s, %p, %#zx)\n", vmem_name(vm), addr, size); 45 | 46 | vmem_free(vm->vm_source, addr, size); 47 | } 48 | 49 | static void 50 | vmem_verbose_add(vmem_t *vm, void *addr, size_t size) 51 | { 52 | vmem_printf("vmem_add(%s, %p, %#zx)\n", vmem_name(vm), addr, size); 53 | 54 | vmem_add(vm->vm_source, addr, size); 55 | } 56 | 57 | static void 58 | vmem_verbose_remove(vmem_t *vm, void *addr, size_t size) 59 | { 60 | vmem_printf("vmem_remove(%s, %p, %#zx)\n", vmem_name(vm), addr, size); 61 | 62 | vmem_remove(vm->vm_source, addr, size); 63 | } 64 | 65 | static size_t 66 | vmem_verbose_walk(vmem_t *vm, vmem_walk_cb *func, void *arg, int w) 67 | { 68 | size_t size = vmem_walk(vm->vm_source, func, arg, w); 69 | 70 | vmem_printf("vmem_walk(%s, %p, %p, %#x) = %#zx\n", 71 | vmem_name(vm), func, arg, w, size); 72 | 73 | return (size); 74 | } 75 | 76 | static void 77 | vmem_verbose_vacate(vmem_t *vm, int v) 78 | { 79 | vmem_printf("vmem_vacate(%s, %#x)\n", vmem_name(vm), v); 80 | 81 | if (v & VMEM_VACATE_SELF_ONLY) 82 | return; 83 | 84 | vmem_vacate(vm->vm_source, v); 85 | } 86 | 87 | static int 88 | vmem_verbose_init(vmem_t *vm) 89 | { 90 | vmem_printf("vmem_init(%s)\n", vmem_name(vm)); 91 | 92 | return (0); 93 | } 94 | 95 | static void 96 | vmem_verbose_fini(vmem_t *vm) 97 | { 98 | vmem_printf("vmem_fini(%s)\n", vmem_name(vm)); 99 | } 100 | 101 | const vmem_ops_t vmem_verbose_ops = { 102 | .vop_xalloc = vmem_verbose_xalloc, 103 | .vop_free = vmem_verbose_free, 104 | .vop_debug = NULL, 105 | .vop_add = vmem_verbose_add, 106 | .vop_remove = vmem_verbose_remove, 107 | .vop_walk = vmem_verbose_walk, 108 | .vop_vacate = vmem_verbose_vacate, 109 | .vop_init = vmem_verbose_init, 110 | .vop_fini = vmem_verbose_fini, 111 | .vop_name = "verbose", 112 | .vop_attr = VMEM_OP_FILTER 113 | }; 114 | -------------------------------------------------------------------------------- /lib/libutrace/ut_parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UT_PARSER_H 18 | #define _UT_PARSER_H 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #define UT_TYPE_VOID 0x000 /* base: void */ 25 | #define UT_TYPE_INT 0x001 /* base: int */ 26 | #define UT_TYPE_CHAR 0x002 /* base: char */ 27 | #define UT_TYPE_WCHAR 0x003 /* base: wchar */ 28 | #define UT_TYPE_STRING 0x004 /* base: string */ 29 | #define UT_TYPE_WSTRING 0x005 /* base: wstring */ 30 | #define UT_TYPE_FLOAT 0x006 /* base: float */ 31 | #define UT_TYPE_STRUCT 0x007 /* base: struct */ 32 | #define UT_TYPE_UNION 0x008 /* base: union */ 33 | #define UT_TYPE_FUNC 0x009 /* base: function */ 34 | 35 | #define UT_TYPE_UNSIGN 0x010 /* flag: unsigned int or char */ 36 | #define UT_TYPE_LONG 0x020 /* flag: long int or double */ 37 | #define UT_TYPE_LLONG 0x040 /* flag: long long or long double */ 38 | #define UT_TYPE_SHORT 0x080 /* flag: short int */ 39 | #define UT_TYPE_PTR 0x100 /* flag: pointer to type */ 40 | #define UT_TYPE_ARRAY 0x200 /* flag: array of type */ 41 | 42 | #define UT_TYPE_BASE(t) ((t) & 0x00F) 43 | #define UT_TYPE_FLAG(t) ((t) & 0xFF0) 44 | 45 | #define UT_TYPE_UINT32 (UT_TYPE_INT | UT_TYPE_UNSIGN) 46 | #define UT_TYPE_UINT64 (UT_TYPE_INT | UT_TYPE_UNSIGN | UT_TYPE_LLONG) 47 | #define UT_TYPE_UINTPTR (UT_TYPE_INT | UT_TYPE_UNSIGN | UT_TYPE_LONG) 48 | 49 | struct ut_pcb; 50 | struct ut_str; 51 | 52 | typedef struct ut_node { 53 | enum yytokentype node_token; 54 | uint16_t node_type; 55 | YYLTYPE node_loc; 56 | YYSTYPE node_value; 57 | struct ut_node *node_lhs; 58 | struct ut_node *node_rhs; 59 | struct ut_node *node_list; 60 | struct ut_node *node_link; 61 | } ut_node_t; 62 | 63 | extern ut_node_t *utrace_node_link(ut_node_t *, ut_node_t *); 64 | extern ut_node_t *utrace_node_ident(const YYLTYPE *, struct ut_pcb *, 65 | const struct ut_str *); 66 | extern ut_node_t *utrace_node_int(const YYLTYPE *, struct ut_pcb *, 67 | unsigned long long); 68 | extern ut_node_t *utrace_node_float(const YYLTYPE *, struct ut_pcb *, 69 | long double); 70 | extern ut_node_t *utrace_node_string(const YYLTYPE *, struct ut_pcb *, 71 | const struct ut_str *); 72 | extern ut_node_t *utrace_node_params(const YYLTYPE *, struct ut_pcb *, 73 | const struct ut_str *, ut_node_t *); 74 | extern ut_node_t *utrace_node_op2(const YYLTYPE *, struct ut_pcb *, 75 | enum yytokentype, ut_node_t *, ut_node_t *); 76 | 77 | typedef void ut_node_f(struct ut_pcb *, ut_node_t *, void *); 78 | extern int utrace_node_walk(struct ut_pcb *, ut_node_t *, ut_node_f *, void *); 79 | 80 | extern void yyuterror(YYLTYPE *, struct ut_pcb *, const char *, ...) 81 | __attribute__((format(printf, 3, 4))); 82 | 83 | extern int yyutlex_destroy(void); 84 | extern int yyutlex(YYSTYPE *, YYLTYPE *, struct ut_pcb *); 85 | extern int yyutparse(struct ut_pcb *); 86 | 87 | extern void yyutinit(struct ut_pcb *); 88 | extern void yyutfini(struct ut_pcb *); 89 | 90 | extern const char *const *ut_token_names; 91 | extern int yyutdebug; 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif /* _UT_PARSER_H */ 98 | -------------------------------------------------------------------------------- /lib/libutrace/ut_vm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UT_VM_H 18 | #define _UT_VM_H 19 | 20 | #include 21 | #include 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | enum ut_opcode { 28 | UT_OPC_TRACE, 29 | UT_OPC_PRINT, 30 | UT_OPC_ABORT, 31 | UT_OPC_STOP, 32 | UT_OPC_PROF_BEGIN, 33 | UT_OPC_PROF_END, 34 | UT_OPC_MAX = 32 35 | }; 36 | 37 | /* 38 | * Note: some opcodes may interpret the ut_vacode in a context-specific way, 39 | * e.g. as an integer. 40 | */ 41 | enum ut_vacode { 42 | UT_VAR_NONE, 43 | UT_VAR_FUNCTION, 44 | UT_VAR_FORMAT, 45 | UT_VAR_ARGS, 46 | UT_VAR_ERRNO, 47 | UT_VAR_STACK, 48 | UT_VAR_CALLER, 49 | UT_VAR_FRAME, 50 | UT_VAR_CYCLES, 51 | UT_VAR_HRTIME, 52 | UT_VAR_CPUID, 53 | UT_VAR_TID, 54 | UT_VAR_PRID, 55 | UT_VAR_EVENT, 56 | UT_VAR_EVENTID, 57 | UT_VAR_FILE, 58 | UT_VAR_LINE, 59 | UT_VAR_MAX = 64 60 | }; 61 | 62 | struct ut_obj; 63 | struct ut_ecb; 64 | 65 | #define UT_VMS_FRAMES 18 66 | #define UT_VMS_FSKIP 2 67 | 68 | typedef struct utrace_vms { 69 | uint32_t utvm_size[UT_VAR_MAX]; 70 | struct ut_obj *utvm_object; 71 | const char *utvm_function; 72 | const char *utvm_format; 73 | va_list utvm_args; 74 | int utvm_errno; 75 | int utvm_depth; 76 | uintptr_t utvm_stack[UT_VMS_FRAMES - UT_VMS_FSKIP]; 77 | const void *utvm_caller; 78 | const void *utvm_frame; 79 | uint64_t utvm_cycles; 80 | uint64_t utvm_hrtime; 81 | int utvm_cpuid; 82 | pthread_t utvm_tid; 83 | int utvm_prid; 84 | const char *utvm_event; 85 | int utvm_eventid; 86 | const char *utvm_file; 87 | uint32_t utvm_line; 88 | } utrace_vms_t; 89 | 90 | /* 91 | * Simple instruction encoding for our microscopic virtual machine: we use 92 | * a 64-bit integer to encode an opcode, argument count, and up to 7 arguments. 93 | * The encoding is depicted in bytes and bits as follows: 94 | * 95 | * 7..B7..0 7..B6..0 7..B5..0 7..B4..0 7..B3..0 7..B2..0 7..B1..0 7..B0..0 96 | * RRVVVVVV RRVVVVVV RRVVVVVV RRVVVVVV RRVVVVVV RRVVVVVV RRVVVVVV OOOOOCCC 97 | * 98 | * RR - 00 - reserved for future use 99 | * VVVVVV - 0..63 - ut_vacode variable id 100 | * OOOOO - 0..31 - ut_opcode operand id 101 | * CCC - 0..7 - number of variables 102 | * 103 | * The fixed encoding makes it simpler for us to precalculate all of the data 104 | * and sizes referenced by an enabling without having to decode the operand. 105 | */ 106 | 107 | #define UT_OPC_ENCODE(opc) ((opc) << 3) 108 | #define UT_ARG_ENCODE(opc, len) (((opc) & ~7) | ((len) & 7)) 109 | 110 | #define UT_INS_OPCODE(ins) (((uint8_t)ins) >> 3) 111 | #define UT_INS_ARGLEN(ins) (((uint8_t)ins) & 7) 112 | #define UT_INS_ARGVAR(ins, arg) ((uint8_t)((ins) >> (((arg) + 1) * 8))) 113 | 114 | extern void utrace_vm_load(utrace_probe_t *, utrace_vms_t *, 115 | const char *, enum utrace_event, const char *, va_list, enum ut_vacode); 116 | 117 | extern void utrace_vm_exec(utrace_probe_t *, utrace_vms_t *, struct ut_ecb *); 118 | 119 | #ifdef __cplusplus 120 | } 121 | #endif 122 | 123 | #endif /* _UT_VM_H */ 124 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_printf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #define VMEM_PRINTF_BUF 1024 21 | #define VMEM_PRINTF_LOG 8192 22 | 23 | char vmem_panicstr[VMEM_PRINTF_BUF]; 24 | char vmem_printf_log[VMEM_PRINTF_LOG + VMEM_PRINTF_BUF]; 25 | 26 | /* 27 | * ============================================================================ 28 | * printf() and panic() routines that don't allocate memory 29 | * ============================================================================ 30 | */ 31 | static void 32 | __attribute__((format(printf, 1, 0))) 33 | vmem_vprintf(const char *fmt, va_list va) 34 | { 35 | static size_t vmem_printf_log_idx = 0; 36 | int saved_errno = errno; 37 | char buf[VMEM_PRINTF_BUF]; 38 | size_t len, idx; 39 | 40 | buf[0] = '\0'; 41 | (void) vsnprintf(buf, sizeof (buf), fmt, va); 42 | len = strlen(buf); 43 | 44 | idx = __sync_fetch_and_add(&vmem_printf_log_idx, len); 45 | bcopy(buf, &vmem_printf_log[idx % VMEM_PRINTF_LOG], len); 46 | 47 | (void) write(fileno(stderr), buf, strlen(buf)); 48 | 49 | errno = saved_errno; 50 | } 51 | 52 | void 53 | __attribute__((format(printf, 1, 2))) 54 | vmem_printf(const char *fmt, ...) 55 | { 56 | va_list va; 57 | 58 | va_start(va, fmt); 59 | vmem_vprintf(fmt, va); 60 | va_end(va); 61 | } 62 | 63 | static void 64 | __attribute__((noreturn)) 65 | __attribute__((format(printf, 1, 0))) 66 | vmem_vpanic(const char *fmt, va_list va) 67 | { 68 | int saved_errno = errno; 69 | static pthread_mutex_t vmem_panic_lock; 70 | (void) pthread_mutex_lock(&vmem_panic_lock); 71 | 72 | (void) vsnprintf(vmem_panicstr, sizeof (vmem_panicstr) - 1, fmt, va); 73 | (void) strcat(vmem_panicstr, "\n"); 74 | (void) write(fileno(stderr), vmem_panicstr, strlen(vmem_panicstr)); 75 | 76 | errno = saved_errno; 77 | abort(); 78 | } 79 | 80 | void 81 | __attribute__((noreturn)) 82 | __attribute__((format(printf, 1, 2))) 83 | vmem_panic(const char *fmt, ...) 84 | { 85 | va_list va; 86 | 87 | va_start(va, fmt); 88 | vmem_vpanic(fmt, va); 89 | va_end(va); 90 | } 91 | 92 | void 93 | __attribute__((noreturn)) 94 | __attribute__((format(printf, 6, 7))) 95 | vmem_panic_xalloc(vmem_t *vm, size_t size, size_t align, size_t phase, int flag, 96 | const char *fmt, ...) 97 | { 98 | va_list va; 99 | char buf[VMEM_PRINTF_BUF]; 100 | 101 | (void) snprintf(buf, sizeof (buf), "vmem_xalloc(vm %p = %s, " 102 | "size %#zx, align %#zx, phase %#zx, flag %#x): %s", 103 | vm, vm->vm_name, size, align, phase, flag, fmt); 104 | 105 | va_start(va, fmt); 106 | vmem_vpanic(buf, va); 107 | va_end(va); 108 | } 109 | 110 | void 111 | __attribute__((noreturn)) 112 | __attribute__((format(printf, 4, 5))) 113 | vmem_panic_free(vmem_t *vm, void *addr, size_t size, const char *fmt, ...) 114 | { 115 | va_list va; 116 | char buf[VMEM_PRINTF_BUF]; 117 | 118 | (void) snprintf(buf, sizeof (buf), 119 | "vmem_free(vm %p = %s, addr %p, size %#zx): %s", 120 | vm, vm->vm_name, addr, size, fmt); 121 | 122 | va_start(va, fmt); 123 | vmem_vpanic(buf, va); 124 | va_end(va); 125 | } 126 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_libc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | /* 21 | * ============================================================================ 22 | * C library malloc equivalents 23 | * ============================================================================ 24 | */ 25 | static inline void * 26 | vmem_libc_alloc(size_t size, size_t align, int zero) 27 | { 28 | vmem_bt_t *bt; 29 | void *addr, *vaddr; 30 | size_t vsize; 31 | size_t page = vmem_pagesize; 32 | 33 | if (align < sizeof (*bt)) 34 | align = sizeof (*bt); 35 | 36 | if (align <= vmem_heap->vm_heap_cache_max) { 37 | vsize = P2ROUNDUP(size, align) + align; 38 | vaddr = vmem_xalloc(vmem_heap, vsize, 0, 0, VM_NOSLEEP); 39 | addr = (void *)P2ROUNDUP((uintptr_t)vaddr, align); 40 | if (addr == vaddr) { 41 | addr += align; 42 | } 43 | } else { 44 | vsize = P2ROUNDUP(size, align) + page; 45 | vaddr = vmem_xalloc(vmem_heap, vsize, align, align - page, 46 | VM_NOSLEEP); 47 | addr = vaddr + page; 48 | } 49 | 50 | if (vaddr == NULL) { 51 | errno = ENOMEM; 52 | return (NULL); 53 | } 54 | 55 | ASSERT(P2PHASE((uintptr_t)addr, align) == 0); 56 | ASSERT(addr >= vaddr + sizeof (*bt)); 57 | ASSERT(addr + size <= vaddr + vsize); 58 | 59 | bt = addr - sizeof (*bt); 60 | bt->bt_vaddr = vaddr; 61 | bt->bt_vsize = vsize; 62 | 63 | if (zero) 64 | bzero(addr, size); 65 | 66 | return (addr); 67 | } 68 | 69 | void 70 | vmem_libc_free(void *addr) 71 | { 72 | vmem_bt_t *bt = addr - sizeof (*bt); 73 | void *vaddr; 74 | 75 | if (addr == NULL) 76 | return; 77 | 78 | vaddr = bt->bt_vaddr; 79 | 80 | if (vaddr == (void *)VMEM_DEBUG_FREE) 81 | vmem_panic("free(%p): double free, bt %p", addr, bt); 82 | 83 | bt->bt_vaddr = (void *)VMEM_DEBUG_FREE; 84 | 85 | vmem_free(vmem_heap, vaddr, bt->bt_vsize); 86 | } 87 | 88 | void * 89 | vmem_libc_malloc(size_t size) 90 | { 91 | return (vmem_libc_alloc(size, 0, 0)); 92 | } 93 | 94 | void * 95 | vmem_libc_calloc(size_t count, size_t size) 96 | { 97 | return (vmem_libc_alloc(size * count, 0, 1)); 98 | } 99 | 100 | void * 101 | vmem_libc_memalign(size_t align, size_t size) 102 | { 103 | return (vmem_libc_alloc(size, align, 0)); 104 | } 105 | 106 | void * 107 | vmem_libc_valloc(size_t size) 108 | { 109 | return (vmem_libc_alloc(size, vmem_pagesize, 0)); 110 | } 111 | 112 | void * 113 | vmem_libc_realloc(void *addr, size_t size) 114 | { 115 | vmem_bt_t *bt = addr - sizeof (*bt); 116 | void *oldvaddr, *newaddr; 117 | size_t oldvsize; 118 | 119 | if (addr == NULL) 120 | return (vmem_libc_alloc(size, 0, 0)); 121 | 122 | oldvaddr = bt->bt_vaddr; 123 | oldvsize = bt->bt_vsize; 124 | 125 | if (oldvaddr == (void *)VMEM_DEBUG_FREE) 126 | vmem_panic("realloc(%p): addr is free, bt %p", addr, bt); 127 | 128 | if (oldvaddr + oldvsize == addr + P2ROUNDUP(size, sizeof (*bt))) 129 | return (addr); 130 | 131 | newaddr = vmem_libc_alloc(size, 0, 0); 132 | 133 | if (newaddr == NULL) 134 | return (NULL); 135 | 136 | bcopy(addr, newaddr, vmem_size_min(oldvaddr + oldvsize - addr, size)); 137 | vmem_libc_free(addr); 138 | 139 | return (newaddr); 140 | } 141 | -------------------------------------------------------------------------------- /lib/libustat/ustat_io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _USTAT_IO_H 18 | #define _USTAT_IO_H 19 | 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* 27 | * Userland Statistics I/O Class 28 | * 29 | * Typical i/o subsystems have two basic queues of transactions they manage: 30 | * one for transactions that have been accepted for processing but for which 31 | * processing has yet to begin, and one for transactions which are actively 32 | * being processed but not yet done. The ustat_io_ functions manage a ustat 33 | * group that tracks the activity of these type of i/o subsystems, including 34 | * the wait (pre-service) time, the run (service) time, IOPS, and bandwidth. 35 | * 36 | * There are three basic abstractions managed by these functions: 37 | * ustat_io_t - accumulated i/o stats for a subsystem 38 | * ustat_iop_t - i/o stats for a single i/o operation 39 | * ustat_io_delta_t - derived i/o stats from the delta between two ustat_io_t's 40 | */ 41 | 42 | typedef struct ustat_io { 43 | ustat_named_t uio_reads; /* number of read ops */ 44 | ustat_named_t uio_rbytes; /* number of read bytes */ 45 | ustat_named_t uio_writes; /* number of write ops */ 46 | ustat_named_t uio_wbytes; /* number of write bytes */ 47 | ustat_named_t uio_cbytes; /* number of copy bytes */ 48 | ustat_named_t uio_wtime; /* time accumulated in wait queue */ 49 | ustat_named_t uio_rtime; /* time accumulated in run queue */ 50 | ustat_named_t uio_ttime; /* time accumulated by all i/o's */ 51 | ustat_named_t uio_utime; /* time recorded at last update */ 52 | ustat_named_t uio_errors; /* number of failed ops */ 53 | ustat_named_t uio_total; /* number of total ops */ 54 | ustat_named_t uio_ctons; /* conversion for hrcyctonsm() */ 55 | } ustat_io_t; 56 | 57 | typedef struct ustat_iop { 58 | uint64_t uiop_init; /* i/o init time (waitq enter) */ 59 | uint64_t uiop_exec; /* i/o exec time (waitq-to-runq) */ 60 | uint64_t uiop_fini; /* i/o fini time (runq exit) */ 61 | uint32_t uiop_rlen; /* i/o read length in bytes */ 62 | uint32_t uiop_wlen; /* i/o write length in bytes */ 63 | uint32_t uiop_clen; /* i/o copy length in bytes */ 64 | uint32_t uiop_errs; /* i/o errors encountered */ 65 | } ustat_iop_t; 66 | 67 | typedef struct ustat_io_delta { 68 | double uiod_delta; /* delta time in seconds */ 69 | uint64_t uiod_t_iops; /* total iops */ 70 | uint64_t uiod_r_iops; /* read iops */ 71 | uint64_t uiod_w_iops; /* write iops */ 72 | uint64_t uiod_r_bw; /* read bytes / sec */ 73 | uint64_t uiod_w_bw; /* write bytes / sec */ 74 | uint64_t uiod_c_bw; /* copy bytes / sec */ 75 | double uiod_avgw_us; /* avg wait usec / iop */ 76 | double uiod_avgr_us; /* avg run usec / iop */ 77 | double uiod_avgt_us; /* avg total usec / iop */ 78 | } ustat_io_delta_t; 79 | 80 | extern const ustat_class_t ustat_class_io; 81 | extern const ustat_iop_t ustat_iop_failed; 82 | 83 | extern void ustat_io_enter(ustat_io_t *, const ustat_iop_t *); 84 | extern void ustat_io_delta(ustat_io_t *, ustat_io_delta_t *); 85 | extern void ustat_io_stats(uint64_t, ustat_io_t *, ustat_io_delta_t *); 86 | extern void ustat_io_merge(ustat_io_t *, const ustat_io_t *); 87 | extern void ustat_io_reset(ustat_io_t *); 88 | 89 | #ifdef __cplusplus 90 | } 91 | #endif 92 | 93 | #endif /* _USTAT_IO_H */ 94 | -------------------------------------------------------------------------------- /lib/libucore/nt_prstatus.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | ssize_t 26 | nt_prstatus_size(NElf_Word type, int fd, off_t off, pid_t tid) 27 | { 28 | return (ucore_note_size(type, "CORE", sizeof (struct elf_prstatus))); 29 | } 30 | 31 | static int 32 | nt_prstatus_sigs(size_t argc, char *argv[], void *data) 33 | { 34 | struct elf_prstatus *p = data; 35 | 36 | if (argc >= 2 && strcmp(argv[0], "SigPnd:") == 0) 37 | (void) sscanf(argv[1], "%lx", &p->pr_sigpend); 38 | else if (argc >= 2 && strcmp(argv[0], "SigBlk:") == 0) 39 | (void) sscanf(argv[1], "%lx", &p->pr_sighold); 40 | 41 | return (0); 42 | } 43 | 44 | static int 45 | nt_prstatus_stat(size_t argc, char *argv[], void *data) 46 | { 47 | const unsigned long tck_per_s = ucore_clktck; 48 | const unsigned long us_per_tck = U_MICROSEC / tck_per_s; 49 | 50 | struct elf_prstatus *p = data; 51 | unsigned long tck; 52 | 53 | (void) sscanf(argv[0], "%d", &p->pr_pid); 54 | (void) sscanf(argv[3], "%d", &p->pr_ppid); 55 | (void) sscanf(argv[4], "%d", &p->pr_pgrp); 56 | (void) sscanf(argv[5], "%d", &p->pr_sid); 57 | 58 | (void) sscanf(argv[13], "%lu", &tck); 59 | p->pr_utime.tv_sec = tck / tck_per_s; 60 | p->pr_utime.tv_usec = (tck % tck_per_s) * us_per_tck; 61 | 62 | (void) sscanf(argv[14], "%lu", &tck); 63 | p->pr_stime.tv_sec = tck / tck_per_s; 64 | p->pr_stime.tv_usec = (tck % tck_per_s) * us_per_tck; 65 | 66 | (void) sscanf(argv[15], "%lu", &tck); 67 | p->pr_cutime.tv_sec = tck / tck_per_s; 68 | p->pr_cutime.tv_usec = (tck % tck_per_s) * us_per_tck; 69 | 70 | (void) sscanf(argv[16], "%lu", &tck); 71 | p->pr_cstime.tv_sec = tck / tck_per_s; 72 | p->pr_cstime.tv_usec = (tck % tck_per_s) * us_per_tck; 73 | 74 | p->pr_fpvalid = 1; 75 | return (0); 76 | } 77 | 78 | ssize_t 79 | nt_prstatus_dump(NElf_Word type, int fd, off_t off, pid_t tid) 80 | { 81 | struct elf_prstatus p; 82 | siginfo_t sig; 83 | 84 | /* 85 | * The current Linux kernel code sets pr_cursig for *every* TID to the 86 | * fatal signal, and ignores pr_info.si_code and si_errno entirely. 87 | * And of course gdb relies upon this behavior, even though it makes 88 | * no sense. So although what we should be doing here is to call 89 | * ptrace(PTRACE_GETSIGINFO) for the non-faulting TIDs, instead we have 90 | * to emulate what Linux core files look like even though it's wrong. 91 | */ 92 | bzero(&p, sizeof (p)); 93 | ucore_getsig(&sig); 94 | 95 | p.pr_info.si_signo = sig.si_signo; 96 | p.pr_cursig = sig.si_signo; 97 | 98 | if (tid == ucore_gettid()) { 99 | p.pr_info.si_code = sig.si_code; 100 | p.pr_info.si_errno = sig.si_errno; 101 | } 102 | 103 | (void) ucore_parse(nt_prstatus_sigs, &p, 104 | "/proc/%d/task/%d/status", ucore_getpid(), tid); 105 | 106 | (void) ucore_parse(nt_prstatus_stat, &p, 107 | "/proc/%d/task/%d/stat", ucore_getpid(), tid); 108 | 109 | if (ptrace(PTRACE_GETREGS, tid, NULL, &p.pr_reg) != 0) 110 | (void) ucore_error(errno, "failed to get gregs for %d", tid); 111 | 112 | if (tid == ucore_gettid()) 113 | ucore_getreg(&p.pr_reg); 114 | 115 | return (ucore_note_dump(fd, off, type, "CORE", &p, sizeof (p))); 116 | } 117 | -------------------------------------------------------------------------------- /lib/libucore/ucore_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -p 2 | 3 | # 4 | # Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | # 20 | # libucore test 21 | # 22 | # There is a massive amount of verification that could be done here, but for 23 | # the moment we cover the basic sanity checking in an automated fashion: 24 | # 25 | # 1. verify that we get a user core and it is valid ELF 26 | # 2. verify that we get a kernel core and it is valid ELF 27 | # 3. verify that we preserve the exit status as WIFSIGNALED and WTERMSIG 28 | # 4. verify that we have the same list of PT_LOAD Phdrs in both core files 29 | # 5. verify that gdb sees the same basic prstatus, stack, and registers 30 | # 31 | # The other stuff that must be hand-verified at the moment includes: 32 | # 33 | # 6. PT_LOAD binary content (other than referenced by 5 above) 34 | # 7. PT_NOTE binary content (other than referenced by 5 above) 35 | # 8. Shdr content for ucore 36 | # 37 | 38 | export PATH=/bin:/usr/bin 39 | shopt -s xpg_echo 40 | 41 | export UCORE_PATH=ucore.%p 42 | export UCORE_OPTIONS=user,kernel,banner 43 | 44 | wstat=$? 45 | errs=0 46 | 47 | function fatal 48 | { 49 | echo "FAIL: $*" >& 2 50 | errs=$(($errs + 1)) 51 | exit $errs 52 | } 53 | 54 | function fail 55 | { 56 | echo "FAIL: $*" >& 2 57 | errs=$(($errs + 1)) 58 | return 1 59 | } 60 | 61 | if [[ $( test.out 2>/dev/null & 73 | pid=$! 74 | wait $pid >/dev/null 2>&1 75 | wstat=$? 76 | echo "done" 77 | 78 | echo "Verifying status ... \c" 79 | [[ $wstat = $((128 + 11)) ]] && echo "SIGSEGV" || \ 80 | fail "unexpected exit status $wstat" >& 2 81 | 82 | function readelf_phdrs 83 | { 84 | readelf -W -l $1 | grep -v $2 | \ 85 | awk '$1=="LOAD" { print $3, $6, $7, $8, $9, $10 }' 86 | } 87 | 88 | function readgdb_stats 89 | { 90 | gdb -q -x /dev/stdin "$@" <<-EOF 2>/dev/null 91 | info registers 92 | backtrace 93 | print rodata 94 | print bss 95 | print heap 96 | print stk 97 | quit 98 | EOF 99 | } 100 | 101 | # 102 | # We need to omit the stack during the comparison because dumping the core 103 | # from libucore, before we return, will push the siginfo_t and ucontext_t 104 | # and therefore may end up lowering the bottom of the stack by one page. 105 | # The test program interrogates itself to figure out its stack base and 106 | # prints that to stdout. 107 | # 108 | stk1=$(cat test.out | grep '^stackbase=' | cut -d= -f2) 109 | [[ -n $stk1 ]] || fatal "could not find stackbase= in test program output" 110 | 111 | stk2=$(($stk1 + 0x1000)) 112 | 113 | stk1=$(printf "0x%16llx\n" $stk1) 114 | stk2=$(printf "0x%16llx\n" $stk2) 115 | 116 | echo "Comparing ELF content ... \c" 117 | readelf_phdrs core.$pid $stk1 $stk2 >kphdrs.$pid 118 | readelf_phdrs ucore.$pid $stk1 $stk2 >uphdrs.$pid 119 | diff kphdrs.$pid uphdrs.$pid && echo "match" || fail "elf mismatch" 120 | 121 | echo "Comparing GDB status ... \c" 122 | readgdb_stats ./ucore_test core.$pid >kgdb.$pid 123 | readgdb_stats ./ucore_test ucore.$pid >ugdb.$pid 124 | diff kgdb.$pid ugdb.$pid && echo "match" || fail "gdb mismatch" 125 | 126 | rm -f test.out core.$pid ucore.$pid kphdrs.$pid uphdrs.$pid kgdb.$pid ugdb.$pid 127 | exit $errs 128 | -------------------------------------------------------------------------------- /include/getpcstack.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _GETPCSTACK_H 18 | #define _GETPCSTACK_H 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #include 25 | #include 26 | 27 | /* 28 | * Get up to pcstack_limit caller addresses, and store them in pcstack. This 29 | * function returns the minimum of the computed depth and pcstack_limit. 30 | * In general, the following approaches to stack backtracing are possible: 31 | * 32 | * A. Use the compiler runtime. GCC provides __builtin_return_address, but 33 | * unfortunately this requires a depth parameter that is constant at compile 34 | * time. One could work around this by simply unrolling VMEM_TX_STACK 35 | * worth of calls to it, and then only using pcstack_limit worth of them, 36 | * but this approach also requires all the code on the stack to have been 37 | * compiled with the same GCC options for it to work, which is unlikely. 38 | * 39 | * B. Use the debugger runtime. Assuming everything has DWARF runtime data 40 | * for handling functions compiled without frame pointers and the like, one 41 | * can walk frame structures, and then as needed execute the DWARF state 42 | * machine to compute the location of the frame and return address. This is 43 | * the approach used by glibc's backtrace(3) on x86_64. Unfortunately, the 44 | * glibc implementation makes use of calls to malloc to process DWARF. This 45 | * is an extremely bad design choice in general and fatal to use in libvmem. 46 | * 47 | * C. Use the ABI. The Solaris implementation relies on the ABI requiring a 48 | * a frame structure with specific stack alignment, and makes use of 49 | * Solaris-specific routines to determine the current thread stack and 50 | * signal stack boundaries to be sure to avoid dereferencing invalid memory. 51 | * 52 | * D. Compromise. Since none of the above approaches work out well on Linux, 53 | * a reasonable set of assumptions is that (1) libvmem itself is compiled 54 | * with GCC so __builtin_frame_address(0) returns a correct starting point; 55 | * (2) if anyone is using the optional VMEM_DEBUG debugging features, they 56 | * must care about debugging, and if they care about debugging, they can be 57 | * smart enough to compile with -fno-omit-frame-pointer; (3) we can 58 | * compile libvmem itself with -fno-omit-frame-pointer to ensure that code 59 | * locations that call getpcstack() have a frame pointer; and (4) most 60 | * functions that call malloc or vmem_alloc() are not the sort that will 61 | * benefit from omitting a frame pointer anyway, i.e. tiny leaf routines. 62 | * 63 | * Overall while distinctly unsatisfying option (D) is the present best choice. 64 | * The two most obvious improvements would be for Linux backtrace(3) to be 65 | * implemented without memory allocation, or for Linux to provide a vsyscall 66 | * akin to Solaris uucopy(2) to permit us to safely check for valid frames. 67 | */ 68 | static inline int 69 | __attribute__((always_inline)) 70 | getpcstack(void **pcstack, int pcstack_limit, int zero) 71 | { 72 | int depth = 0; 73 | void **f = __builtin_frame_address(0); 74 | 75 | for (void **lastf = f - 1; // f[0]=next frame, f[1]=pc 76 | IS_P2ALIGNED(f, sizeof (void *)) && // frame is pointer-aligned 77 | f > lastf && // stack grows down 78 | f < lastf + (1UL << 20) && // frame size < 1M* plausible 79 | f[1] > (void *)4096 && // pc plausible -- not page 0 80 | depth < pcstack_limit; lastf = f, f = f[0]) 81 | pcstack[depth++] = f[1]; 82 | 83 | for (int d = zero ? depth : pcstack_limit; d < pcstack_limit; d++) 84 | pcstack[d++] = NULL; 85 | 86 | return (depth); 87 | } 88 | 89 | #ifdef __cplusplus 90 | } 91 | #endif 92 | 93 | #endif /* _GETPCSTACK_H */ 94 | -------------------------------------------------------------------------------- /lib/libbson/utf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | /* 20 | * The UTF-8 encoding represents any Unicode character from U+0000 to U+10FFFF 21 | * (the defined limit) as a sequence of 1-4 bytes using a Huffman-like coding: 22 | * 23 | * ------------------+--------------------------------------------- 24 | * 00000000-0000007F | 0xxxxxxx 25 | * 00000080-000007FF | 110xxxxx 10xxxxxx 26 | * 00000800-0000FFFF | 1110xxxx 10xxxxxx 10xxxxxx 27 | * 00010000-0010FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 28 | * ------------------+--------------------------------------------- 29 | */ 30 | 31 | static const uint32_t utf8_max[5] = { 0, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF }; 32 | static const uint8_t utf8_tag[6] = { 0x80, 0x00, 0xC0, 0xE0, 0xF0, 0xF8 }; 33 | static const uint8_t utf8_mask[6] = { 0x3F, 0x7F, 0x1F, 0x0F, 0x07, 0x03 }; 34 | static const int8_t utf8_shift[6] = { 6, 7, 5, 4, 3, 2 }; 35 | 36 | static const uint32_t unicode_sp_base = 0x10000; 37 | static const uint32_t unicode_sp_shift = 10; 38 | static const uint32_t unicode_sp_mask = 0x3FF; 39 | static const uint32_t unicode_sp1_start = 0xD800; 40 | static const uint32_t unicode_sp1_end = 0xDBFF; 41 | static const uint32_t unicode_sp2_start = 0xDC00; 42 | static const uint32_t unicode_sp2_end = 0xDFFF; 43 | 44 | int 45 | unicode_is_sp(uint32_t u) 46 | { 47 | return (u >= unicode_sp_base); 48 | } 49 | 50 | int 51 | unicode_is_sp1(uint32_t u1) 52 | { 53 | return (u1 >= unicode_sp1_start && u1 <= unicode_sp1_end); 54 | } 55 | 56 | int 57 | unicode_is_sp2(uint32_t u2) 58 | { 59 | return (u2 >= unicode_sp2_start && u2 <= unicode_sp2_end); 60 | } 61 | 62 | void 63 | unicode_to_sp(uint32_t u, uint32_t *u1, uint32_t *u2) 64 | { 65 | u -= unicode_sp_base; 66 | 67 | *u1 = unicode_sp1_start + (u >> unicode_sp_shift); 68 | *u2 = unicode_sp2_start + (u & unicode_sp_mask); 69 | } 70 | 71 | uint32_t 72 | unicode_from_sp(uint32_t u1, uint32_t u2) 73 | { 74 | u1 -= unicode_sp1_start; 75 | u2 -= unicode_sp2_start; 76 | 77 | return (unicode_sp_base + (u1 << unicode_sp_shift) + u2); 78 | } 79 | 80 | char * 81 | unicode_to_utf8_n(uint32_t u, char *s, int n) 82 | { 83 | for (int i = n - 1; i != 0; i--) { 84 | s[i] = (u & utf8_mask[0]) | utf8_tag[0]; 85 | u >>= utf8_shift[0]; 86 | } 87 | 88 | s[0] = (char)(u + utf8_tag[n]); 89 | 90 | return (s + n); 91 | } 92 | 93 | const char * 94 | unicode_from_utf8_n(uint32_t *u, const char *s, int n) 95 | { 96 | uint32_t u1, c; 97 | uint32_t ux = 0; 98 | 99 | for (u1 = (uint8_t)*s++ - utf8_tag[n--]; n; n--) { 100 | c = (uint8_t)*s++ - utf8_tag[0]; 101 | u1 = (u1 << utf8_shift[0]) ^ c; 102 | ux |= c; 103 | } 104 | 105 | *u = u1; 106 | 107 | return (ux > utf8_mask[0] ? NULL : s); 108 | } 109 | 110 | char * 111 | unicode_to_utf8(uint32_t u, char *s) 112 | { 113 | if (u <= utf8_max[1]) { 114 | return (unicode_to_utf8_n(u, s, 1)); 115 | } else if (u <= utf8_max[2]) { 116 | return (unicode_to_utf8_n(u, s, 2)); 117 | } else if (u <= utf8_max[3]) { 118 | return (unicode_to_utf8_n(u, s, 3)); 119 | } else if (u <= utf8_max[4]) { 120 | return (unicode_to_utf8_n(u, s, 4)); 121 | } 122 | return (NULL); 123 | } 124 | 125 | const char * 126 | unicode_from_utf8(uint32_t *u, const char *s) 127 | { 128 | uint8_t c = (uint8_t)*s; 129 | 130 | if (c < utf8_tag[0]) { 131 | return (unicode_from_utf8_n(u, s, 1)); 132 | } else if (c < utf8_tag[2]) { 133 | return (NULL); 134 | } else if (c < utf8_tag[3]) { 135 | return (unicode_from_utf8_n(u, s, 2)); 136 | } else if (c < utf8_tag[4]) { 137 | return (unicode_from_utf8_n(u, s, 3)); 138 | } else if (c < utf8_tag[5]) { 139 | s = unicode_from_utf8_n(u, s, 4); 140 | if (*u <= utf8_max[4]) 141 | return (s); 142 | } 143 | return (NULL); 144 | } 145 | -------------------------------------------------------------------------------- /lib/libutrace/ut_pcb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | static const ut_var_t 20 | utrace_pcb_builtin[] = { 21 | { "abort", UT_OPC_ABORT, UT_TYPE_FUNC, utrace_func_empty }, 22 | { "args", UT_VAR_ARGS, UT_TYPE_UINTPTR, NULL }, 23 | { "caller", UT_VAR_CALLER, UT_TYPE_UINTPTR, NULL }, 24 | { "cpuid", UT_VAR_CPUID, UT_TYPE_UINT32, NULL }, 25 | { "cycles", UT_VAR_CYCLES, UT_TYPE_UINT64, NULL }, 26 | { "errno", UT_VAR_ERRNO, UT_TYPE_INT, NULL }, 27 | { "event", UT_VAR_EVENT, UT_TYPE_STRING, NULL }, 28 | { "eventid", UT_VAR_EVENTID, UT_TYPE_INT, NULL }, 29 | { "file", UT_VAR_FILE, UT_TYPE_STRING, NULL }, 30 | { "format", UT_VAR_FORMAT, UT_TYPE_STRING, NULL }, 31 | { "frame", UT_VAR_FRAME, UT_TYPE_UINTPTR, NULL }, 32 | { "function", UT_VAR_FUNCTION, UT_TYPE_STRING, NULL }, 33 | { "hrtime", UT_VAR_HRTIME, UT_TYPE_UINT64, NULL }, 34 | { "line", UT_VAR_LINE, UT_TYPE_INT, NULL }, 35 | { "prid", UT_VAR_PRID, UT_TYPE_UINT32, NULL }, 36 | { "print", UT_OPC_PRINT, UT_TYPE_FUNC, utrace_func_nonempty }, 37 | { "stack", UT_VAR_STACK, UT_TYPE_STRUCT, NULL }, 38 | { "stop", UT_OPC_STOP, UT_TYPE_FUNC, utrace_func_empty }, 39 | { "tid", UT_VAR_TID, UT_TYPE_UINTPTR, NULL }, 40 | { "trace", UT_OPC_TRACE, UT_TYPE_FUNC, utrace_func_nonempty }, 41 | { "prof_begin", UT_OPC_PROF_BEGIN, UT_TYPE_FUNC, utrace_func_prof }, 42 | { "prof_end", UT_OPC_PROF_END, UT_TYPE_FUNC, utrace_func_prof }, 43 | { NULL, 0, 0, NULL } 44 | }; 45 | 46 | static int 47 | __attribute__((pure)) 48 | utrace_pcb_strcmp(const void *lp, const void *rp) 49 | { 50 | const ut_str_t *s1 = lp; 51 | const ut_str_t *s2 = rp; 52 | 53 | return (strcmp(s1->str_data, s2->str_data)); 54 | } 55 | 56 | const ut_str_t * 57 | utrace_pcb_string(ut_pcb_t *pcb, const char *str) 58 | { 59 | ut_str_t o, *s; 60 | 61 | o.str_size = strlen(str) + 1; 62 | o.str_data = (char *)str; 63 | 64 | if ((s = tree_lookup(&pcb->pcb_strings, &o)) != NULL) 65 | return (s); 66 | 67 | s = vmem_alloc(vmem_heap, sizeof (*s), VM_SLEEP); 68 | 69 | s->str_vref = NULL; 70 | s->str_data = vmem_alloc(vmem_heap, o.str_size, VM_SLEEP); 71 | s->str_size = o.str_size; 72 | 73 | bcopy(str, s->str_data, s->str_size); 74 | tree_insert(&pcb->pcb_strings, s); 75 | 76 | return (s); 77 | } 78 | 79 | /* 80 | * Initialize the parser control block (pcb), which includes a tree for unique 81 | * strings encountered during compilation, and a cache of all parse tree nodes. 82 | * The pcb is used to share state across ut_lex.l, ut_grammar.y, and ut_parser.c 83 | */ 84 | void 85 | utrace_pcb_init(utrace_handle_t *uhp, ut_pcb_t *pcb, FILE *fp) 86 | { 87 | const ut_var_t *vp; 88 | 89 | bzero(pcb, sizeof (*pcb)); 90 | 91 | tree_init(&pcb->pcb_strings, 92 | utrace_pcb_strcmp, offsetof(ut_str_t, str_node)); 93 | 94 | pcb->pcb_nodes = vmem_create(&vmem_object_ops, 95 | __alignof__(ut_node_t), sizeof (ut_node_t), 96 | vmem_page, NULL, NULL, 0, "pcb_%p", pcb); 97 | 98 | for (vp = utrace_pcb_builtin; vp->var_name != NULL; vp++) { 99 | const ut_str_t *s = utrace_pcb_string(pcb, vp->var_name); 100 | ((ut_str_t *)s)->str_vref = vp; 101 | } 102 | 103 | pcb->pcb_hdl = uhp; 104 | pcb->pcb_stdin = fp; 105 | pcb->pcb_depth = 1; 106 | 107 | yyutinit(pcb); 108 | } 109 | 110 | /* ARGSUSED */ 111 | static void 112 | ut_str_destroy(void *p, void *arg) 113 | { 114 | ut_str_t *str = p; 115 | vmem_free(vmem_heap, str->str_data, str->str_size); 116 | vmem_free(vmem_heap, str, sizeof (*str)); 117 | } 118 | 119 | void 120 | utrace_pcb_fini(utrace_handle_t *uhp, ut_pcb_t *pcb) 121 | { 122 | yyutfini(pcb); 123 | tree_teardown(&pcb->pcb_strings, ut_str_destroy, NULL); 124 | tree_fini(&pcb->pcb_strings); 125 | vmem_vacate(pcb->pcb_nodes, VMEM_VACATE_ALL); 126 | vmem_destroy(pcb->pcb_nodes); 127 | } 128 | -------------------------------------------------------------------------------- /lib/libucore/ucore_impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UCORE_IMPL_H 18 | #define _UCORE_IMPL_H 19 | 20 | /* 21 | * ucore_impl.h - include file for nt_*.c implementations 22 | * 23 | * At present, linux/elfcore.h defines the structures shared between the 24 | * Linux kernel core dump code and its consumer, gdb. This file in turn 25 | * requires other kernel source files to compile, making for quite a mess: it 26 | * appears the mental model here is just copying structs and not an interface. 27 | * Also, elfcore.h can only compile with the kernel's elf.h, not userland elf.h. 28 | * 29 | * The following hacks make it possible to compile our nt_*.c source against 30 | * linux/elfcore.h without becoming an entire kernel compilation environment. 31 | * This is brittle and stupid, but the only alternative is struct duplication. 32 | * If this .h file starts to break frequently, that may be a better alternative. 33 | */ 34 | 35 | #include 36 | #include 37 | 38 | #if defined(__arm__) 39 | /* The user struct names are different/missing on ARM compared to x86 */ 40 | #define user_regs_struct user_regs 41 | #define user_fpregs_struct user_fpregs 42 | struct user_fpxregs_struct 43 | { 44 | }; 45 | #endif /* __arm__ */ 46 | 47 | #if defined(_ELF_H) 48 | #include 49 | #include 50 | #else 51 | #include 52 | #include 53 | 54 | typedef __pid_t pid_t; 55 | typedef __ssize_t ssize_t; 56 | typedef __UWORD_TYPE size_t; 57 | 58 | typedef unsigned long elf_greg_t; 59 | typedef struct user_regs_struct elf_gregset_t; 60 | typedef struct user_fpregs_struct elf_fpregset_t; 61 | typedef struct user_fpxregs_struct elf_fpxregset_t; 62 | 63 | #include 64 | #include 65 | #endif 66 | 67 | #include 68 | 69 | #ifdef __cplusplus 70 | extern "C" { 71 | #endif 72 | 73 | /* 74 | * is mostly just needless duplication of the contents of 75 | * , save for the ptrace(2) prototype itself. On older 76 | * Linux versions, they can both be included (if done in the right order), 77 | * but this fragile arrangement breaks on newer kernels. We define ptrace(2) 78 | * ourselves here so we can avoid and use 79 | * (which is included transitively outside our control). 80 | */ 81 | extern long int ptrace(int, ...); 82 | 83 | /* 84 | * Interfaces between core file note generators and the common libucore code. 85 | * Notes must provide two functions: note_size(), to just report the size of 86 | * the note in bytes, and note_dump(), to actually write out the data buffer. 87 | */ 88 | typedef ssize_t ucore_note_f(NElf_Word, int, off_t, pid_t); 89 | 90 | typedef struct ucore_note { 91 | NElf_Word note_type; 92 | ucore_note_f *note_size; 93 | ucore_note_f *note_dump; 94 | } ucore_note_t; 95 | 96 | extern size_t ucore_pgsize; /* _SC_PAGESIZE */ 97 | extern long ucore_clktck; /* _SC_CLK_TCK */ 98 | 99 | extern pid_t ucore_getpid(void); 100 | extern pid_t ucore_gettid(void); 101 | extern void ucore_getreg(struct user_regs_struct *); 102 | extern void ucore_getsig(siginfo_t *); 103 | extern void *ucore_page_alloc(void); 104 | extern void ucore_page_free(void *); 105 | 106 | extern int ucore_error(int, const char *, ...) 107 | __attribute__ ((format(printf, 2, 3))); 108 | 109 | #define UCORE_S_STR 1 /* slurp string */ 110 | #define UCORE_S_BIN 2 /* slurp binary */ 111 | 112 | extern ssize_t ucore_slurp(int, char *, size_t, const char *, ...) 113 | __attribute__ ((format(printf, 4, 5))); 114 | 115 | extern int ucore_parse(int (*)(size_t, char *[], void *), void *, 116 | const char *, ...) __attribute__ ((format(printf, 3, 4))); 117 | 118 | extern ssize_t ucore_note_size(NElf_Word, const char *, size_t); 119 | extern ssize_t ucore_note_dump(int, off_t, 120 | NElf_Word, const char *, const void *, size_t); 121 | extern ssize_t ucore_note_regs(NElf_Word, int, off_t, 122 | pid_t, const char *, size_t); 123 | 124 | extern ucore_note_f nt_prstatus_size; 125 | extern ucore_note_f nt_prstatus_dump; 126 | extern ucore_note_f nt_prpsinfo_size; 127 | extern ucore_note_f nt_prpsinfo_dump; 128 | extern ucore_note_f nt_auxv_size; 129 | extern ucore_note_f nt_auxv_dump; 130 | extern ucore_note_f nt_fpregset_size; 131 | extern ucore_note_f nt_fpregset_dump; 132 | extern ucore_note_f nt_prxfpreg_size; 133 | extern ucore_note_f nt_prxfpreg_dump; 134 | extern ucore_note_f nt_xstate_size; 135 | extern ucore_note_f nt_xstate_dump; 136 | 137 | #ifdef __cplusplus 138 | } 139 | #endif 140 | 141 | #endif /* _UCORE_IMPL_H */ 142 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_sleep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | /* 20 | * ============================================================================ 21 | * Sleep/wakeup 22 | * ============================================================================ 23 | */ 24 | static void 25 | vmem_vacate_cb(vmem_t *vm, void *addr, size_t size, void *arg) 26 | { 27 | /* 28 | * We cannot claw back memory from single-threaded arenas, 29 | * because only the owning thread is allowed to touch them. 30 | */ 31 | if (vm->vm_flag & VM_THREAD) 32 | return; 33 | 34 | vmem_vacate(vm, (int)(uintptr_t)arg | VMEM_VACATE_SELF_ONLY); 35 | } 36 | 37 | static void 38 | vmem_wait_cb(vmem_t *vm, void *addr, size_t size, void *arg) 39 | { 40 | if (vm == vm->vm_base) { 41 | (void) pthread_mutex_lock(&vm->vm_lock); 42 | vm->vm_waiters += (intptr_t)arg; 43 | (void) pthread_mutex_unlock(&vm->vm_lock); 44 | } 45 | } 46 | 47 | /* 48 | * Retry a failed allocation, sleeping if necessary until memory is available. 49 | */ 50 | void * 51 | vmem_xalloc_sleep(vmem_t *vm, size_t size, size_t align, size_t phase, int flag) 52 | { 53 | void *addr; 54 | vmem_t *ovm; 55 | size_t wakeups; 56 | int err; 57 | 58 | if (!(flag & (VM_SLEEP | VM_NOFAIL))) // no retry necessary 59 | return (NULL); 60 | 61 | if (flag & VM_NORETRY) // no retry allowed 62 | return (NULL); 63 | 64 | flag |= VM_NORETRY; // prevent recursion 65 | 66 | /* 67 | * Normally, we attempt to reclaim memory from every arena that 68 | * consumes from the same origin as vm. If VM_RECYCLE is specified, 69 | * we only reclaim from vm itself, so the origin is vm->vm_base; 70 | * otherwise it's vm->vm_origin, which is right above the root. 71 | */ 72 | ovm = (flag & VM_RECYCLE) ? vm->vm_base : vm->vm_origin; 73 | 74 | /* 75 | * Vacate caches in every arena above the origin and try again. 76 | */ 77 | (void) vmem_root.vm_ops.vop_walk(ovm, vmem_vacate_cb, 78 | (void *)VMEM_VACATE_CACHE, VMEM_WALK_POST); 79 | 80 | addr = vmem_xalloc(vm, size, align, phase, flag); 81 | 82 | if (addr != NULL) 83 | return (addr); 84 | 85 | if (!(flag & VM_SLEEP)) 86 | vmem_panic_xalloc(vm, size, align, phase, flag, 87 | "NOFAIL failed"); 88 | 89 | /* 90 | * VM_SLEEP is set, so for every arena above the origin, 91 | * disable caching and increment waiters. 92 | */ 93 | (void) vmem_root.vm_ops.vop_walk(ovm, vmem_vacate_cb, 94 | (void *)VMEM_VACATE_CACHE_DISABLE, VMEM_WALK_POST); 95 | 96 | (void) vmem_root.vm_ops.vop_walk(ovm, vmem_wait_cb, 97 | (void *)1UL, VMEM_WALK_PRE); 98 | 99 | /* 100 | * Now, keep trying until memory shows up. By default, we will sleep 101 | * indefinitely waiting for a free(). If the client has customized 102 | * the vm_sleep() callback, sleep can be interrupted when the callback 103 | * returns non-zero, at which point a VM_SLEEP allocation will fail. 104 | */ 105 | wakeups = -1UL; 106 | err = 0; 107 | 108 | while (addr == NULL) { 109 | (void) pthread_mutex_lock(&ovm->vm_lock); 110 | while (err == 0 && ovm->vm_wakeups == wakeups) 111 | err = ovm->vm_sleep(ovm, &ovm->vm_cv, &ovm->vm_lock); 112 | wakeups = ovm->vm_wakeups; 113 | (void) pthread_mutex_unlock(&ovm->vm_lock); 114 | 115 | if (err != 0) 116 | break; /* sleep error or interrupted; return NULL */ 117 | 118 | addr = vmem_xalloc(vm, size, align, phase, flag); 119 | } 120 | 121 | /* 122 | * For every arena above the origin, 123 | * decrement waiters and reenable caching. 124 | */ 125 | (void) vmem_root.vm_ops.vop_walk(ovm, vmem_wait_cb, 126 | (void *)-1UL, VMEM_WALK_POST); 127 | 128 | (void) vmem_root.vm_ops.vop_walk(ovm, vmem_vacate_cb, 129 | (void *)VMEM_VACATE_CACHE_ENABLE, VMEM_WALK_PRE); 130 | 131 | return (addr); 132 | } 133 | 134 | /* 135 | * Notify waiters that memory is available. This is invoked by vop_free() 136 | * of each base arena when it notices vm->vm_waiters != 0. This check 137 | * can be done without locking because it can only cause false positives 138 | * (unnecessary wakeups). It cannot cause false negatives because the 139 | * memory that was just freed became visible while the lock was held, 140 | * so any newly-arrived waiters must have already seen that and found it 141 | * insufficient to satisfy the allocation. 142 | */ 143 | void 144 | vmem_free_wakeup(vmem_t *vm) 145 | { 146 | for (vmem_t *ovm = vm; ovm != NULL; ovm = ovm->vm_source) { 147 | ovm = ovm->vm_base; 148 | (void) pthread_mutex_lock(&ovm->vm_lock); 149 | if (ovm->vm_waiters) { 150 | ovm->vm_wakeups++; 151 | (void) ovm->vm_wakeup(ovm, &ovm->vm_cv); 152 | } 153 | (void) pthread_mutex_unlock(&ovm->vm_lock); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_heap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | /* 20 | * ============================================================================ 21 | * Heap operations 22 | * ============================================================================ 23 | */ 24 | static void * 25 | vmem_heap_xalloc(vmem_t *vm, size_t size, size_t align, size_t phase, int flag) 26 | { 27 | vmem_t *cvm; 28 | 29 | if (!IS_P2(align)) 30 | vmem_panic_xalloc(vm, size, align, phase, flag, "bad args"); 31 | 32 | if (align <= vm->vm_q) 33 | align = 1; 34 | 35 | if ((size - 1) < vm->vm_heap_cache_max) { 36 | if (P2PHASE(size, align) != 0) 37 | vmem_panic_xalloc(vm, size, align, phase, flag, 38 | "size not aligned"); 39 | if (phase >= align) 40 | vmem_panic_xalloc(vm, size, align, phase, flag, 41 | "address-constrained small heap allocation"); 42 | cvm = vm->vm_heap_cache[(size - 1) >> vm->vm_qshift]; 43 | } else { 44 | cvm = vm->vm_heap_byte; 45 | } 46 | 47 | if (align < cvm->vm_q) 48 | align = cvm->vm_q; 49 | 50 | if (P2PHASE(phase, cvm->vm_q) != 0) 51 | cvm = vm->vm_heap_byte; 52 | 53 | size = P2ROUNDUP(size, cvm->vm_q); 54 | 55 | return (vmem_xalloc(cvm, size, align, phase, flag)); 56 | } 57 | 58 | static void 59 | vmem_heap_free(vmem_t *vm, void *addr, size_t size) 60 | { 61 | vmem_t *cvm; 62 | 63 | if ((size - 1) < vm->vm_heap_cache_max) { 64 | cvm = vm->vm_heap_cache[(size - 1) >> vm->vm_qshift]; 65 | } else { 66 | cvm = vm->vm_heap_byte; 67 | } 68 | 69 | if (P2PHASE((uintptr_t)addr, cvm->vm_q) != 0) 70 | cvm = vm->vm_heap_byte; 71 | 72 | size = P2ROUNDUP(size, cvm->vm_q); 73 | 74 | vmem_free(cvm, addr, size); 75 | } 76 | 77 | static void 78 | vmem_heap_add(vmem_t *vm, void *addr, size_t size) 79 | { 80 | vmem_add(vm->vm_source, addr, size); 81 | } 82 | 83 | static void 84 | vmem_heap_remove(vmem_t *vm, void *addr, size_t size) 85 | { 86 | vmem_t *cvm; 87 | 88 | for (cvm = list_head(&vm->vm_heap_list); cvm != NULL; 89 | cvm = list_next(&vm->vm_heap_list, cvm)) 90 | vmem_vacate(cvm, VMEM_VACATE_CACHE); 91 | 92 | vmem_remove(vm->vm_source, addr, size); 93 | } 94 | 95 | static size_t 96 | vmem_heap_walk(vmem_t *vm, vmem_walk_cb *func, void *arg, int w) 97 | { 98 | vmem_t *cvm; 99 | size_t wsize = 0; 100 | 101 | for (cvm = list_head(&vm->vm_heap_list); cvm != NULL; 102 | cvm = list_next(&vm->vm_heap_list, cvm)) 103 | wsize += vmem_walk(cvm, func, arg, w); 104 | 105 | return (wsize); 106 | } 107 | 108 | static void 109 | vmem_heap_vacate(vmem_t *vm, int v) 110 | { 111 | vmem_t *cvm; 112 | 113 | if (v & VMEM_VACATE_SELF_ONLY) 114 | return; 115 | 116 | for (cvm = list_head(&vm->vm_heap_list); cvm != NULL; 117 | cvm = list_next(&vm->vm_heap_list, cvm)) 118 | vmem_vacate(cvm, v); 119 | } 120 | 121 | static int 122 | vmem_heap_init(vmem_t *vm) 123 | { 124 | vmem_t *svm = vm->vm_source; 125 | vmem_t *cvm; 126 | size_t size, align, qsize = 0, s = 0; 127 | 128 | if (vm->vm_object == 0 || svm == NULL) 129 | return (-1); 130 | 131 | vm->vm_heap_cache_max = vm->vm_object; 132 | vm->vm_object = 0; 133 | 134 | while (!IS_P2(vm->vm_heap_cache_max)) 135 | vm->vm_heap_cache_max += P2ALIGNOF(vm->vm_heap_cache_max); 136 | 137 | list_init(&vm->vm_heap_list, offsetof(vmem_t, vm_heap_node)); 138 | 139 | vm->vm_heap_cache = vmem_alloc(vmem_find_self(vm), 140 | P2ROUNDUP(vm->vm_heap_cache_max / vm->vm_q * sizeof (void *), 141 | vmem_pagesize), VM_SLEEP); 142 | 143 | for (size = vm->vm_q; size <= vm->vm_heap_cache_max; size += qsize) { 144 | if (!IS_P2ALIGNED(size, vm->vm_q)) 145 | continue; 146 | if (IS_P2(size)) 147 | qsize = size >> 2; 148 | if (qsize == 0) 149 | qsize = 1; 150 | align = P2ALIGNOF(size); 151 | 152 | cvm = vmem_create(&vmem_object_ops, align, size, svm, 153 | vm->vm_construct, vm->vm_destruct, vm->vm_flag, 154 | "%s_%zu", vm->vm_name, size); 155 | 156 | for (; s < size; s += vm->vm_q) 157 | vm->vm_heap_cache[s >> vm->vm_qshift] = cvm; 158 | 159 | list_insert_tail(&vm->vm_heap_list, cvm); 160 | } 161 | 162 | vm->vm_heap_byte = vmem_create(&vmem_variable_ops, vm->vm_q, 0, svm, 163 | vm->vm_construct, vm->vm_destruct, vm->vm_flag, 164 | "%s_byte", vm->vm_name); 165 | 166 | list_insert_tail(&vm->vm_heap_list, vm->vm_heap_byte); 167 | 168 | return (0); 169 | } 170 | 171 | static void 172 | vmem_heap_fini(vmem_t *vm) 173 | { 174 | vmem_t *cvm; 175 | 176 | while ((cvm = list_delete_tail(&vm->vm_heap_list)) != NULL) 177 | vmem_destroy(cvm); 178 | 179 | vmem_free(vmem_find_self(vm), vm->vm_heap_cache, 180 | P2ROUNDUP(vm->vm_heap_cache_max / vm->vm_q * sizeof (void *), 181 | vmem_pagesize)); 182 | 183 | list_fini(&vm->vm_heap_list); 184 | } 185 | 186 | const vmem_ops_t vmem_heap_ops = { 187 | .vop_xalloc = vmem_heap_xalloc, 188 | .vop_free = vmem_heap_free, 189 | .vop_debug = NULL, 190 | .vop_add = vmem_heap_add, 191 | .vop_remove = vmem_heap_remove, 192 | .vop_walk = vmem_heap_walk, 193 | .vop_vacate = vmem_heap_vacate, 194 | .vop_init = vmem_heap_init, 195 | .vop_fini = vmem_heap_fini, 196 | .vop_name = "heap", 197 | .vop_attr = VMEM_OP_BASE | VMEM_OP_MUX 198 | }; 199 | -------------------------------------------------------------------------------- /lib/libustat/ustat_impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _USTAT_IMPL_H 18 | #define _USTAT_IMPL_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | typedef struct ustat_ifmt { 31 | const char *usf_i8; 32 | const char *usf_i16; 33 | const char *usf_i32; 34 | const char *usf_i64; 35 | const char *usf_u8; 36 | const char *usf_u16; 37 | const char *usf_u32; 38 | const char *usf_u64; 39 | const char *usf_u8_first; 40 | const char *usf_u8_rest; 41 | const char *usf_u64_first; 42 | const char *usf_u64_rest; 43 | } ustat_ifmt_t; 44 | 45 | #define USTAT_MAG0 0x7f 46 | #define USTAT_MAG1 0x55 47 | #define USTAT_MAG2 0x53 48 | 49 | #define USTAT_MAG3_32 0x01 50 | #define USTAT_MAG3_64 0x02 51 | #define USTAT_MAG3_LE 0x04 52 | #define USTAT_MAG3_BE 0x08 53 | #define USTAT_MAG3_ROOT 0x10 54 | #define USTAT_MAG3_GRP 0x20 55 | 56 | #define USTAT_MAG3_BASE 0x0f 57 | #define USTAT_MAG3_TYPE 0xf0 58 | 59 | #if __BYTE_ORDER == __LITTLE_ENDIAN 60 | #if __WORDSIZE == 64 61 | #define USTAT_MAG3 (USTAT_MAG3_LE | USTAT_MAG3_64) 62 | #elif __WORDSIZE == 32 63 | #define USTAT_MAG3 (USTAT_MAG3_LE | USTAT_MAG3_32) 64 | #endif 65 | #elif __BYTE_ORDER == __BIG_ENDIAN 66 | #if __WORDSIZE == 64 67 | #define USTAT_MAG3 (USTAT_MAG3_BE | USTAT_MAG3_64) 68 | #elif __WORDSIZE == 32 69 | #define USTAT_MAG3 (USTAT_MAG3_BE | USTAT_MAG3_32) 70 | #endif 71 | #elif __BYTE_ORDER == __BIG_ENDIAN 72 | #endif 73 | 74 | typedef struct ustat_page { 75 | uint8_t usp_magic[4]; 76 | uint32_t usp_size; 77 | void *usp_addr; 78 | off_t usp_off; 79 | } ustat_page_t; 80 | 81 | typedef struct ustat_group { 82 | struct ustat_group *usg_next; 83 | struct ustat_group *usg_prev; 84 | ustat_handle_t *usg_handle; 85 | const char *usg_gname; 86 | const char *usg_cname; 87 | void *usg_carg; 88 | void *usg_uarg; 89 | uint64_t usg_ctime; 90 | uint64_t usg_atime; 91 | uint16_t usg_flags; 92 | uint16_t usg_statc; 93 | ustat_named_t *usg_statv; 94 | ustat_value_t *usg_datav; 95 | char *usg_rodata; 96 | uint8_t *usg_rwdata; 97 | } ustat_group_t; 98 | 99 | /* 100 | * These structs must be kept in sync with the above native types. 101 | * They exist to provide a way of importing / exporting ustats 102 | * between different systems, e.g. 64-bit to 32-bit. 103 | */ 104 | typedef struct ustat_page64 { 105 | uint8_t usp_magic[4]; 106 | uint32_t usp_size; 107 | uint64_t usp_addr; 108 | uint64_t usp_off; 109 | } ustat_page64_t; 110 | 111 | typedef struct ustat_group64 { 112 | uint64_t usg_next; 113 | uint64_t usg_prev; 114 | uint64_t usg_handle; 115 | uint64_t usg_gname; 116 | uint64_t usg_cname; 117 | uint64_t usg_carg; 118 | uint64_t usg_uarg; 119 | uint64_t usg_ctime; 120 | uint64_t usg_atime; 121 | uint16_t usg_flags; 122 | uint16_t usg_statc; 123 | uint64_t usg_statv; 124 | uint64_t usg_datav; 125 | uint64_t usg_rodata; 126 | uint64_t usg_rwdata; 127 | } ustat_group64_t; 128 | 129 | #define USTAT_DATA_TO_PAGE(h, x) \ 130 | ((ustat_page_t *)P2ALIGN((uintptr_t)x, h->ush_pgsize)) 131 | 132 | #define USTAT_PAGE_TO_DATA(p) \ 133 | ((void *)P2ROUNDUP((uintptr_t)p + sizeof (ustat_page_t), 16)) 134 | 135 | #define USTAT_PAGE64_TO_DATA(p) \ 136 | ((uint64_t)P2ROUNDUP((uint64_t)p + sizeof (ustat_page64_t), 16)) 137 | 138 | #define USTAT_STRUCT_TO_GROUP(s) \ 139 | ((ustat_group_t *)((uintptr_t)s - sizeof (ustat_group_t))) 140 | 141 | #define USTAT_GROUP_TO_STRUCT(g) \ 142 | ((ustat_struct_t *)((uintptr_t)g + sizeof (ustat_group_t))) 143 | 144 | #define USTAT_F_INSERTED 0x1 /* ustat_insert() called on me */ 145 | #define USTAT_F_UNLINKED 0x2 /* ustat_unlink() called on me */ 146 | 147 | typedef struct ustat_root { 148 | uint32_t usr_gen; 149 | pid_t usr_pid; 150 | char *usr_comm; 151 | char *usr_args; 152 | ustat_group_t **usr_hash; 153 | size_t usr_hlen; 154 | } ustat_root_t; 155 | 156 | typedef struct ustat_freepage { 157 | list_node_t usfp_node; 158 | off_t usfp_off; 159 | size_t usfp_size; 160 | } ustat_freepage_t; 161 | 162 | struct ustat_handle { 163 | int ush_version; 164 | int ush_oflags; 165 | ustat_handle_t *ush_link; 166 | ustat_root_t *ush_root; 167 | pthread_rwlock_t ush_lock; 168 | int (*ush_update)(struct ustat_handle *); 169 | size_t ush_pgsize; 170 | char *ush_path; 171 | int ush_fd; 172 | size_t ush_fdlen; 173 | list_t ush_free_pgsz; 174 | list_t ush_free_other; 175 | int ush_self; 176 | int ush_ismem; 177 | }; 178 | 179 | extern int ustat_set_bson_object(bson_t *b, off_t d, off_t *nd, 180 | const char *utype, const char *nname); 181 | extern int ustat_add_bson_group(ustat_struct_t *s, bson_t *b, off_t d, 182 | off_t *nd); 183 | extern int ustat_set_bson_i64(bson_t *b, off_t d, const char *utype, 184 | const char *nname, int64_t val); 185 | extern int ustat_set_bson_str(bson_t *b, off_t d, 186 | const char *utype, const char *nname, const char *str); 187 | extern int ustat_set_bson_array(ustat_struct_t *s, bson_t *b, off_t d, 188 | off_t *nd, const char *utype, const char *nname); 189 | 190 | extern int ustat_set_bson_cyctons(ustat_struct_t *s, bson_t *b, off_t d, 191 | ustat_named_t *n, uint64_t cycle_mult); 192 | 193 | 194 | #ifdef __cplusplus 195 | } 196 | #endif 197 | 198 | #endif /* _USTAT_IMPL_H */ 199 | -------------------------------------------------------------------------------- /lib/libutrace/ut_parser.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | void 20 | utrace_func_empty(ut_pcb_t *pcb, ut_node_t *f) 21 | { 22 | if (f->node_list != NULL) { 23 | yyuterror(&f->node_loc, pcb, "unexpected arguments " 24 | "for function: %s", f->node_value.l_str->str_data); 25 | } 26 | } 27 | 28 | void 29 | utrace_func_nonempty(ut_pcb_t *pcb, ut_node_t *f) 30 | { 31 | if (f->node_list == NULL) { 32 | yyuterror(&f->node_loc, pcb, "expected one or more arguments " 33 | "for function: %s", f->node_value.l_str->str_data); 34 | } 35 | } 36 | 37 | void 38 | utrace_func_prof(ut_pcb_t *pcb, ut_node_t *f) 39 | { 40 | if (f->node_list == NULL || f->node_list->node_token != UT_TOK_INT || 41 | f->node_list->node_link != NULL) { 42 | yyuterror(&f->node_loc, pcb, "expected one int argument " 43 | "for function: %s", f->node_value.l_str->str_data); 44 | } 45 | } 46 | 47 | static ut_node_t * 48 | utrace_node_alloc(const YYLTYPE *lp, ut_pcb_t *pcb) 49 | { 50 | ut_node_t *n = vmem_alloc(pcb->pcb_nodes, sizeof (*n), VM_SLEEP); 51 | 52 | n->node_token = UT_TOK_EOF; 53 | n->node_type = UT_TYPE_VOID; 54 | n->node_loc = *lp; 55 | n->node_lhs = NULL; 56 | n->node_rhs = NULL; 57 | n->node_list = NULL; 58 | n->node_link = NULL; 59 | 60 | return (n); 61 | } 62 | 63 | ut_node_t * 64 | utrace_node_link(ut_node_t *l, ut_node_t *r) 65 | { 66 | ut_node_t *n; 67 | 68 | if (l == NULL) 69 | return (r); 70 | 71 | if (r == NULL) 72 | return (l); 73 | 74 | for (n = l; n->node_link != NULL; n = n->node_link) 75 | continue; 76 | 77 | n->node_link = r; 78 | return (l); 79 | } 80 | 81 | ut_node_t * 82 | utrace_node_ident(const YYLTYPE *lp, ut_pcb_t *pcb, const ut_str_t *name) 83 | { 84 | ut_node_t *n = utrace_node_alloc(lp, pcb); 85 | 86 | n->node_token = UT_TOK_IDENT; 87 | n->node_value.l_str = name; 88 | 89 | return (n); 90 | } 91 | 92 | ut_node_t * 93 | utrace_node_int(const YYLTYPE *lp, ut_pcb_t *pcb, unsigned long long val) 94 | { 95 | ut_node_t *n = utrace_node_alloc(lp, pcb); 96 | 97 | n->node_token = UT_TOK_INT; 98 | n->node_value.l_int = val; 99 | 100 | return (n); 101 | } 102 | 103 | ut_node_t * 104 | utrace_node_float(const YYLTYPE *lp, ut_pcb_t *pcb, long double val) 105 | { 106 | ut_node_t *n = utrace_node_alloc(lp, pcb); 107 | 108 | n->node_token = UT_TOK_FLOAT; 109 | n->node_value.l_float = val; 110 | 111 | return (n); 112 | } 113 | 114 | ut_node_t * 115 | utrace_node_string(const YYLTYPE *lp, ut_pcb_t *pcb, const ut_str_t *name) 116 | { 117 | ut_node_t *n = utrace_node_alloc(lp, pcb); 118 | 119 | n->node_token = UT_TOK_STRING; 120 | n->node_value.l_str = name; 121 | 122 | return (n); 123 | } 124 | 125 | ut_node_t * 126 | utrace_node_params(const YYLTYPE *lp, ut_pcb_t *pcb, 127 | const ut_str_t *name, ut_node_t *args) 128 | { 129 | ut_node_t *n = utrace_node_alloc(lp, pcb); 130 | 131 | n->node_token = UT_TOK_IDENT; 132 | n->node_value.l_str = name; 133 | n->node_list = args; 134 | 135 | return (n); 136 | } 137 | 138 | ut_node_t * 139 | utrace_node_op2(const YYLTYPE *lp, ut_pcb_t *pcb, 140 | enum yytokentype token, ut_node_t *lhs, ut_node_t *rhs) 141 | { 142 | ut_node_t *n = utrace_node_alloc(lp, pcb); 143 | 144 | n->node_token = token; 145 | n->node_lhs = lhs; 146 | n->node_rhs = rhs; 147 | 148 | return (n); 149 | } 150 | 151 | static void 152 | utrace_node_rwalk(ut_pcb_t *pcb, ut_node_t *rp, 153 | ut_node_f *func, void *arg, int depth) 154 | { 155 | const ut_var_t *vp = NULL; 156 | ut_node_t *cp; 157 | 158 | switch (rp->node_token) { 159 | case UT_KEY_ON: 160 | utrace_dprintf("%*sON\n", depth * 2, ""); 161 | break; 162 | 163 | case UT_TOK_IDENT: 164 | utrace_dprintf("%*s%s\n", depth * 2, "", 165 | rp->node_value.l_str->str_data); 166 | 167 | if ((vp = rp->node_value.l_str->str_vref) == NULL) { 168 | yyuterror(&rp->node_loc, pcb, 169 | "undefined identifier: %s", 170 | rp->node_value.l_str->str_data); 171 | rp->node_type = UT_TYPE_VOID; 172 | } else { 173 | if (vp->var_cook != NULL) 174 | vp->var_cook(pcb, rp); 175 | rp->node_type = vp->var_type; 176 | } 177 | break; 178 | 179 | case UT_TOK_INT: 180 | utrace_dprintf("%*s%llu\n", 181 | depth * 2, "", rp->node_value.l_int); 182 | rp->node_type = UT_TYPE_INT; 183 | break; 184 | 185 | case UT_TOK_FLOAT: 186 | utrace_dprintf("%*s%Lg\n", 187 | depth * 2, "", rp->node_value.l_float); 188 | rp->node_type = UT_TYPE_FLOAT; 189 | break; 190 | 191 | case UT_TOK_STRING: 192 | utrace_dprintf("%*s\"%s\"\n", 193 | depth * 2, "", rp->node_value.l_str->str_data); 194 | rp->node_type = UT_TYPE_STRING; 195 | break; 196 | } 197 | 198 | for (cp = rp->node_lhs; cp != NULL; cp = cp->node_link) 199 | utrace_node_rwalk(pcb, cp, func, arg, depth + 1); 200 | 201 | for (cp = rp->node_rhs; cp != NULL; cp = cp->node_link) 202 | utrace_node_rwalk(pcb, cp, func, arg, depth + 1); 203 | 204 | for (cp = rp->node_list; cp != NULL; cp = cp->node_link) 205 | utrace_node_rwalk(pcb, cp, func, arg, depth + 1); 206 | 207 | if (func != NULL) 208 | func(pcb, rp, arg); 209 | } 210 | 211 | int 212 | utrace_node_walk(ut_pcb_t *pcb, ut_node_t *rp, ut_node_f *func, void *arg) 213 | { 214 | for (; rp != NULL; rp = rp->node_link) 215 | utrace_node_rwalk(pcb, rp, func, arg, 0); 216 | 217 | return (pcb->pcb_errs); 218 | } 219 | -------------------------------------------------------------------------------- /include/atomic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef ATOMIC_H 18 | #define ATOMIC_H 19 | 20 | #include 21 | 22 | #if defined(__i386__) || defined(__x86_64__) 23 | #include 24 | #endif 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Auto-generate inline functions for all atomics of the following forms: 32 | * 33 | * atomic_{add,sub,or,xor,and,nand}_{8,16,32,64}{,_ov,_nv}(ptr, value); 34 | * atomic_{inc,dec}_{8,16,32,64}{,_ov,_nv}(ptr, value); 35 | * atomic_cas_{8,16,32,64,ptr}(ptr, old, new); 36 | * 37 | * The _ov() and _nv() variants return the old and new values, respectively. 38 | * With no suffix, the return type is void. For example: 39 | * 40 | * uint32_t atomic_add_32_nv(uint32_t *p, uint32_t v) => return (*p += v); 41 | * 42 | * It's a bit off-putting to use macros to generate these functions, 43 | * but it's a lot less error-prone -- and a lot easier to modify -- than 44 | * a giant list of 101 hand-coded functions. (It really is 101 functions: 45 | * 6 (add etc) * 4 * 3 + 2 (inc/dec) * 4 * 3 + 5 (cas) = 72 + 24 + 5 = 101.) 46 | */ 47 | #define ATOMIC_OP_SIZE(op, b) \ 48 | static inline void \ 49 | __attribute__((always_inline)) \ 50 | atomic_##op##_##b(uint##b##_t *p, uint##b##_t v) \ 51 | { \ 52 | (void)__sync_fetch_and_##op(p, v); \ 53 | } \ 54 | static inline uint##b##_t \ 55 | __attribute__((always_inline)) \ 56 | atomic_##op##_##b##_ov(uint##b##_t *p, uint##b##_t v) \ 57 | { \ 58 | return (__sync_fetch_and_##op(p, v)); \ 59 | } \ 60 | static inline uint##b##_t \ 61 | __attribute__((always_inline)) \ 62 | atomic_##op##_##b##_nv(uint##b##_t *p, uint##b##_t v) \ 63 | { \ 64 | return (__sync_##op##_and_fetch(p, v)); \ 65 | } 66 | 67 | #define ATOMIC_ALIAS_SIZE(alias, op, v, b) \ 68 | static inline void \ 69 | __attribute__((always_inline)) \ 70 | atomic_##alias##_##b(uint##b##_t *p) \ 71 | { \ 72 | (void)__sync_fetch_and_##op(p, v); \ 73 | } \ 74 | static inline uint##b##_t \ 75 | __attribute__((always_inline)) \ 76 | atomic_##alias##_##b##_ov(uint##b##_t *p) \ 77 | { \ 78 | return (__sync_fetch_and_##op(p, v)); \ 79 | } \ 80 | static inline uint##b##_t \ 81 | __attribute__((always_inline)) \ 82 | atomic_##alias##_##b##_nv(uint##b##_t *p) \ 83 | { \ 84 | return (__sync_##op##_and_fetch(p, v)); \ 85 | } 86 | 87 | #define ATOMIC_CAS_SIZE(b) \ 88 | static inline uint##b##_t \ 89 | __attribute__((always_inline)) \ 90 | atomic_cas_##b(volatile uint##b##_t *p, uint##b##_t o, uint##b##_t n) \ 91 | { \ 92 | return (__sync_val_compare_and_swap(p, o, n)); \ 93 | } 94 | 95 | #define ATOMIC_ALIAS(alias, op, v) \ 96 | ATOMIC_ALIAS_SIZE(alias, op, v, 8) \ 97 | ATOMIC_ALIAS_SIZE(alias, op, v, 16) \ 98 | ATOMIC_ALIAS_SIZE(alias, op, v, 32) \ 99 | ATOMIC_ALIAS_SIZE(alias, op, v, 64) 100 | 101 | #define ATOMIC_OP(op) \ 102 | ATOMIC_OP_SIZE(op, 8) \ 103 | ATOMIC_OP_SIZE(op, 16) \ 104 | ATOMIC_OP_SIZE(op, 32) \ 105 | ATOMIC_OP_SIZE(op, 64) 106 | 107 | ATOMIC_OP(add) 108 | ATOMIC_OP(sub) 109 | ATOMIC_OP(or) 110 | ATOMIC_OP(xor) 111 | ATOMIC_OP(and) 112 | ATOMIC_OP(nand) 113 | 114 | ATOMIC_ALIAS(inc, add, 1) 115 | ATOMIC_ALIAS(dec, sub, 1) 116 | 117 | ATOMIC_CAS_SIZE(8) 118 | ATOMIC_CAS_SIZE(16) 119 | ATOMIC_CAS_SIZE(32) 120 | ATOMIC_CAS_SIZE(64) 121 | 122 | /* 123 | * GCC supports __int128 extension to generate cmpxchg16b on x86_64, but there 124 | * is no uint128_t posix type support yet so we can't use the macro expansion. 125 | */ 126 | #if defined(__x86_64__) 127 | static inline __int128 128 | __attribute__((always_inline)) 129 | atomic_cas_128(volatile __int128 *p, __int128 o, __int128 n) 130 | { 131 | return (__sync_val_compare_and_swap(p, o, n)); 132 | } 133 | #endif 134 | 135 | /* 136 | * Unfortunately, ANSI C casting rules are broken in that foo_t ** cannot 137 | * be automatically converted to void **, so we declare 'p' as void * here. 138 | */ 139 | static inline void * 140 | __attribute__((always_inline)) 141 | atomic_cas_ptr(volatile void *p, void *o, void *n) 142 | { 143 | return (__sync_val_compare_and_swap((void **)p, o, n)); 144 | } 145 | 146 | 147 | /* 148 | * Barriers 149 | */ 150 | 151 | #if defined(__i386__) || defined(__x86_64__) 152 | 153 | static inline void 154 | __attribute__((always_inline)) 155 | mem_lfence(void) 156 | { 157 | _mm_lfence(); 158 | } 159 | 160 | static inline void 161 | __attribute__((always_inline)) 162 | mem_sfence(void) 163 | { 164 | _mm_sfence(); 165 | } 166 | 167 | static inline void 168 | __attribute__((always_inline)) 169 | mem_mfence(void) 170 | { 171 | _mm_mfence(); 172 | } 173 | 174 | #elif defined(__arm__) 175 | 176 | static inline void 177 | __attribute__((always_inline)) 178 | mem_lfence(void) 179 | { 180 | asm("dmb"); 181 | } 182 | 183 | static inline void 184 | __attribute__((always_inline)) 185 | mem_sfence(void) 186 | { 187 | asm("dmb"); 188 | } 189 | 190 | static inline void 191 | __attribute__((always_inline)) 192 | mem_mfence(void) 193 | { 194 | asm("dmb"); 195 | } 196 | 197 | #else 198 | #error "unknown arch" 199 | #endif // defined(__i386__) || defined(__x86_64__) 200 | 201 | 202 | #ifdef __cplusplus 203 | } 204 | #endif 205 | 206 | #endif /* ATOMIC_H */ 207 | -------------------------------------------------------------------------------- /lib/libvmem/vmem_root.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | /* 20 | * ============================================================================ 21 | * Root operations. 22 | * 23 | * The root arena keeps track of all the others. It maintains vmem_list -- 24 | * a list of all arenas in creation order -- and the vm_users tree, in which 25 | * each vm's children are its users (i.e. arenas whose vm_source is vm). 26 | * The root's vm_lock protects both vmem_list and the vm_users tree. 27 | * 28 | * vmem_list defines the lock ordering: when locking all arenas for fork(), 29 | * we first lock the root (which protects vmem_list), then lock every arena 30 | * in reverse creation order. This is also the order in which all arenas 31 | * are destroyed by vmem_fini(), which issues a vmem_vacate() of vmem_root. 32 | * 33 | * vmem_create() adds newly-created arenas to the root using vmem_add(), and 34 | * vmem_destroy() removes them from the root using vmem_remove(). 35 | * 36 | * vmem_walk() of the root arena walks the vm_users tree, and can be done 37 | * in either pre-order or post-order. It is often useful to walk just the 38 | * users of a given arena, not of the entire root; this can be done by 39 | * invoking vmem_root.vm_ops.vop_walk() on that arena. The implementation 40 | * of sleep and wakeup -- which reclaim memory recursively from vm_users -- 41 | * takes full advantage of this mechanism. 42 | * ============================================================================ 43 | */ 44 | static list_t vmem_list; 45 | 46 | void 47 | vmem_root_lock(void) 48 | { 49 | vmem_t *vm; 50 | 51 | (void) pthread_mutex_lock(&vmem_root.vm_lock); 52 | 53 | for (vm = list_tail(&vmem_list); vm; vm = list_prev(&vmem_list, vm)) { 54 | if (vm->vm_mag_arena != NULL) { 55 | for (int c = 0; c < vmem_max_cpus; c++) { 56 | vmem_cpu_t *cpu = &vm->vm_cpu[c]; 57 | (void) pthread_mutex_lock(&cpu->cpu_lock); 58 | } 59 | } 60 | (void) pthread_mutex_lock(&vm->vm_lock); 61 | (void) vm->vm_wakeup(vm, &vm->vm_cv); 62 | } 63 | } 64 | 65 | void 66 | vmem_root_unlock(void) 67 | { 68 | vmem_t *vm; 69 | 70 | for (vm = list_head(&vmem_list); vm; vm = list_next(&vmem_list, vm)) { 71 | if (vm->vm_mag_arena != NULL) { 72 | for (int c = 0; c < vmem_max_cpus; c++) { 73 | vmem_cpu_t *cpu = &vm->vm_cpu[c]; 74 | (void) pthread_mutex_unlock(&cpu->cpu_lock); 75 | } 76 | } 77 | (void) vm->vm_wakeup(vm, &vm->vm_cv); 78 | (void) pthread_mutex_unlock(&vm->vm_lock); 79 | } 80 | 81 | (void) pthread_mutex_unlock(&vmem_root.vm_lock); 82 | } 83 | 84 | /* 85 | * ============================================================================ 86 | * Root ops vector 87 | * ============================================================================ 88 | */ 89 | static void 90 | vmem_root_add(vmem_t *root, void *addr, size_t size) 91 | { 92 | vmem_t *vm = addr; 93 | vmem_t *source = vm->vm_source ? vm->vm_source : root; 94 | 95 | if (vm != root) { 96 | (void) pthread_mutex_lock(&root->vm_lock); 97 | list_insert_tail(&source->vm_users, vm); 98 | list_insert_tail(&vmem_list, vm); 99 | (void) pthread_mutex_unlock(&root->vm_lock); 100 | } 101 | 102 | list_init(&vm->vm_users, offsetof(vmem_t, vm_user_node)); 103 | } 104 | 105 | static void 106 | vmem_root_remove(vmem_t *root, void *addr, size_t size) 107 | { 108 | vmem_t *vm = addr; 109 | vmem_t *source = vm->vm_source ? vm->vm_source : root; 110 | 111 | list_fini(&vm->vm_users); 112 | 113 | if (vm != root) { 114 | (void) pthread_mutex_lock(&root->vm_lock); 115 | list_delete(&source->vm_users, vm); 116 | list_delete(&vmem_list, vm); 117 | (void) pthread_mutex_unlock(&root->vm_lock); 118 | } 119 | } 120 | 121 | static size_t 122 | vmem_root_walk(vmem_t *vm, vmem_walk_cb *func, void *arg, int w) 123 | { 124 | size_t count = 1; 125 | vmem_t *uvm; 126 | 127 | if (!(w & (VMEM_WALK_PRE | VMEM_WALK_POST))) 128 | return (0); 129 | 130 | if (!(w & VMEM_WALK_LOCK)) 131 | (void) pthread_mutex_lock(&vmem_root.vm_lock); 132 | 133 | if (w & VMEM_WALK_PRE) 134 | func(vm, vm, vm->vm_depth, arg); 135 | 136 | for (uvm = list_head(&vm->vm_users); uvm; 137 | uvm = list_next(&vm->vm_users, uvm)) 138 | count += vmem_root_walk(uvm, func, arg, w | VMEM_WALK_LOCK); 139 | 140 | if (w & VMEM_WALK_POST) 141 | func(vm, vm, vm->vm_depth, arg); 142 | 143 | if (!(w & VMEM_WALK_LOCK)) 144 | (void) pthread_mutex_unlock(&vmem_root.vm_lock); 145 | 146 | return (count); 147 | } 148 | 149 | static void 150 | vmem_root_vacate(vmem_t *root, int v) 151 | { 152 | vmem_t *vm; 153 | 154 | if (!(v & VMEM_VACATE_BASE)) 155 | return; 156 | 157 | while ((vm = list_tail(&vmem_list)) != NULL) 158 | vmem_destroy(vm); 159 | } 160 | 161 | static int 162 | vmem_root_init(vmem_t *root) 163 | { 164 | list_init(&vmem_list, offsetof(vmem_t, vm_list_node)); 165 | 166 | return (0); 167 | } 168 | 169 | static void 170 | vmem_root_fini(vmem_t *root) 171 | { 172 | list_fini(&vmem_list); 173 | } 174 | 175 | const vmem_ops_t vmem_root_ops = { 176 | .vop_xalloc = NULL, 177 | .vop_free = NULL, 178 | .vop_debug = NULL, 179 | .vop_add = vmem_root_add, 180 | .vop_remove = vmem_root_remove, 181 | .vop_walk = vmem_root_walk, 182 | .vop_vacate = vmem_root_vacate, 183 | .vop_init = vmem_root_init, 184 | .vop_fini = vmem_root_fini, 185 | .vop_name = "root", 186 | .vop_attr = VMEM_OP_BASE | VMEM_OP_ROOT 187 | }; 188 | -------------------------------------------------------------------------------- /cmd/qat/qat.xsd: -------------------------------------------------------------------------------- 1 | 2 | 28 | 29 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 84 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /lib/libvmem/vmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _VMEM_H 18 | #define _VMEM_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Unified vmem flags 32 | */ 33 | typedef enum vmem_flag { 34 | /* 35 | * Allocation sleep/fail behavior 36 | */ 37 | VM_NOSLEEP = 0x00000000, /* may fail, won't sleep */ 38 | VM_SLEEP = 0x00000001, /* sleep until resource available */ 39 | VM_RECYCLE = 0x00000002, /* sleep only for frees to self */ 40 | VM_NOFAIL = 0x00000004, /* succeed or abort process */ 41 | 42 | /* 43 | * Properties 44 | */ 45 | VM_VIRTUAL = 0x00000100, /* not load/store memory */ 46 | VM_LIMITED = 0x00000200, /* limited resource; advisory */ 47 | VM_RESERVED = 0x00000400, /* cannot use for vmem metadata */ 48 | VM_NOCACHE = 0x00000800, /* do not insert magazine layer */ 49 | VM_NOBULK = 0x00001000, /* do not perform bulk imports */ 50 | VM_REALIZES = 0x00002000, /* produces load/store memory */ 51 | VM_THREAD = 0x00004000, /* single-threaded use; no locking */ 52 | VM_PREALLOC = 0x00008000, /* preallocate and map backing memory */ 53 | 54 | /* 55 | * Debug control 56 | */ 57 | VM_DEBUG = 0x00010000, /* always do debugging */ 58 | VM_NODEBUG = 0x00020000, /* never do debugging */ 59 | VM_MINDEBUG = 0x00040000, /* do *at most* minimal debugging */ 60 | 61 | /* 62 | * Internal 63 | */ 64 | VM_NORETRY = 0x10000000, /* prevents recursion */ 65 | VM_DYNALLOC = 0x20000000, /* vmem itself was dynamically allocd */ 66 | 67 | } vmem_flag_t; 68 | 69 | typedef enum vmem_walk { 70 | VMEM_WALK_ALLOC = 0x00000001, /* walk allocated segments */ 71 | VMEM_WALK_FREE = 0x00000002, /* walk free segments */ 72 | VMEM_WALK_DEBUG = 0x10000000, /* internal: set arg = vmem_debug_t */ 73 | VMEM_WALK_LOCK = 0x20000000, /* internal: walk is already locked */ 74 | VMEM_WALK_PRE = 0x40000000, /* internal: walk users in pre-order */ 75 | VMEM_WALK_POST = 0x80000000, /* internal: walk users in post-order */ 76 | } vmem_walk_t; 77 | 78 | typedef enum vmem_vacate { 79 | VMEM_VACATE_BASE = 0x01, /* vacate base allocations */ 80 | VMEM_VACATE_CACHE = 0x02, /* vacate cache contents */ 81 | VMEM_VACATE_CACHE_DISABLE = 0x04, /* disable and vacate cache */ 82 | VMEM_VACATE_CACHE_ENABLE = 0x08, /* enable cache */ 83 | VMEM_VACATE_SELF_ONLY = 0x10, /* non-recusrive */ 84 | VMEM_VACATE_ALL = VMEM_VACATE_BASE | VMEM_VACATE_CACHE 85 | } vmem_vacate_t; 86 | 87 | typedef struct vmem vmem_t; 88 | typedef struct vmem_ops vmem_ops_t; 89 | 90 | typedef void *vmem_alloc_f(vmem_t *, size_t, int); 91 | typedef void *vmem_xalloc_f(vmem_t *, size_t, size_t, size_t, int); 92 | typedef void *vmem_claim_f(vmem_t *, void *, size_t, int); 93 | typedef void vmem_free_f(vmem_t *, void *, size_t); 94 | 95 | typedef void *vmem_construct_f(const vmem_t *, void *, size_t, int); 96 | typedef void vmem_destruct_f(const vmem_t *, void *, size_t); 97 | typedef int vmem_sleep_f(vmem_t *, pthread_cond_t *, pthread_mutex_t *); 98 | typedef int vmem_wakeup_f(vmem_t *, pthread_cond_t *); 99 | 100 | typedef void vmem_walk_cb(vmem_t *, void *, size_t, void *); 101 | 102 | extern vmem_t *vmem_pages[UNUMA_MAX_NODES][UNUMA_PGT_MAX]; 103 | extern vmem_t *vmem_heaps[UNUMA_MAX_NODES]; 104 | extern vmem_t *vmem_page; /* deprecated: use vmem_pages instead */ 105 | extern vmem_t *vmem_heap; /* deprecated: use vmem_heaps instead */ 106 | extern vmem_t vmem_root; 107 | extern char vmem_panicstr[]; 108 | extern char vmem_printf_log[]; 109 | 110 | extern int vmem_max_cpus; 111 | extern bool vmem_quick_exit; 112 | 113 | extern const vmem_ops_t vmem_object_ops; 114 | extern const vmem_ops_t vmem_variable_ops; 115 | extern const vmem_ops_t vmem_heap_ops; 116 | 117 | extern const vmem_ops_t vmem_verbose_ops; 118 | 119 | extern vmem_t *vmem_create(const vmem_ops_t *, size_t, size_t, 120 | vmem_t *, vmem_construct_f *, vmem_destruct_f *, int, 121 | const char *, ...) __attribute__((format(printf, 8, 9))); 122 | extern void vmem_destroy(vmem_t *); 123 | extern vmem_t *vmem_push(vmem_t *, const vmem_ops_t *); 124 | extern vmem_t *vmem_pop(vmem_t *); 125 | extern void *vmem_alloc(vmem_t *, size_t, int); 126 | extern void *vmem_zalloc(vmem_t *, size_t, int); 127 | extern void *vmem_xalloc(vmem_t *, size_t, size_t, size_t, int); 128 | extern void *vmem_claim(vmem_t *, void *, size_t, int); 129 | extern void vmem_free(vmem_t *, void *, size_t); 130 | extern void vmem_add(vmem_t *, void *, size_t); 131 | extern void vmem_remove(vmem_t *, void *, size_t); 132 | extern size_t vmem_walk(vmem_t *, vmem_walk_cb *, void *, int); 133 | extern void vmem_vacate(vmem_t *, int); 134 | 135 | extern char *vmem_strdup(vmem_t *, const char *, int); 136 | extern int vmem_sprintf(vmem_t *, int, char **, const char *, ...) 137 | __attribute__((format(printf, 4, 5))); 138 | extern int vmem_vsprintf(vmem_t *, int, char **, const char *, va_list) 139 | __attribute__((format(printf, 4, 0))); 140 | extern void vmem_strfree(vmem_t *, char *); 141 | 142 | extern const char *vmem_name(const vmem_t *) __attribute__((pure)); 143 | extern size_t vmem_align(const vmem_t *) __attribute__((pure)); 144 | extern size_t vmem_object(const vmem_t *) __attribute__((pure)); 145 | extern size_t vmem_cache_min(void) __attribute__((pure)); 146 | extern int vmem_get_numa(const vmem_t *, int *, unuma_pgt_t *); 147 | 148 | extern void vmem_setprivate(vmem_t *, void *); 149 | extern void *vmem_getprivate(const vmem_t *); 150 | extern pthread_cond_t *vmem_setsleep(vmem_t *, vmem_sleep_f *, vmem_wakeup_f *); 151 | 152 | extern void *vmem_libc_malloc(size_t); 153 | extern void *vmem_libc_calloc(size_t, size_t); 154 | extern void *vmem_libc_memalign(size_t, size_t); 155 | extern void *vmem_libc_valloc(size_t); 156 | extern void *vmem_libc_realloc(void *, size_t); 157 | extern void vmem_libc_free(void *); 158 | 159 | #ifdef __cplusplus 160 | } 161 | #endif 162 | 163 | #endif /* _VMEM_H */ 164 | -------------------------------------------------------------------------------- /include/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIST_H 18 | #define _LIST_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* 30 | * Inline doubly-linked list routines 31 | * 32 | * list_init(l, off) initialize a list; nodes at offset 'off' 33 | * list_fini(l) finish using a list; must be empty 34 | * list_move(src, dst) move src to dst and clear src 35 | * list_prev(l, n) return node before n, NULL if none 36 | * list_next(l, n) return node after n, NULL if none 37 | * list_head(l) return list head, NULL if empty 38 | * list_tail(l) return list tail, NULL if empty 39 | * list_insert_before(l, b, n) insert node n before b 40 | * list_insert_after(l, a, n) insert node n after a 41 | * list_insert_head(l, n) insert node n at head of the list 42 | * list_insert_tail(l, n) insert node n at tail of the list 43 | * list_delete(l, n) delete node n from the list 44 | * list_delete_head(l) delete head of the list and return it, or NULL 45 | * list_delete_tail(l) delete tail of the list and return it, or NULL 46 | * list_empty(l) return true if the list is empty, false if not 47 | */ 48 | struct list_node; 49 | 50 | typedef struct list_node { 51 | struct list_node *n_prev; 52 | struct list_node *n_next; 53 | } list_node_t; 54 | 55 | typedef struct list { 56 | size_t l_off; 57 | list_node_t l_anchor; 58 | } list_t; 59 | 60 | static inline void * 61 | __attribute__((always_inline)) 62 | __attribute__((pure)) 63 | list_node_to_data(const list_t *l, const list_node_t *n) 64 | { 65 | if (n == &l->l_anchor) 66 | return (NULL); 67 | 68 | return ((void *)((uintptr_t)n - l->l_off)); 69 | } 70 | 71 | static inline list_node_t * 72 | __attribute__((always_inline)) 73 | __attribute__((pure)) 74 | list_node_from_data(const list_t *l, const void *data) 75 | { 76 | if (data == NULL) 77 | return ((list_node_t *)&l->l_anchor); 78 | 79 | return ((list_node_t *)((uintptr_t)data + l->l_off)); 80 | } 81 | 82 | static inline void 83 | __attribute__((always_inline)) 84 | list_node_insert(list_node_t *t, list_node_t *p, list_node_t *n) 85 | { 86 | t->n_prev = p; 87 | t->n_next = n; 88 | n->n_prev = t; 89 | p->n_next = t; 90 | } 91 | 92 | static inline void 93 | __attribute__((always_inline)) 94 | list_node_delete(list_node_t *t) 95 | { 96 | list_node_t *p = t->n_prev; 97 | list_node_t *n = t->n_next; 98 | 99 | n->n_prev = p; 100 | p->n_next = n; 101 | t->n_prev = NULL; 102 | t->n_next = NULL; 103 | } 104 | 105 | static inline void 106 | list_init(list_t *l, size_t off) 107 | { 108 | l->l_off = off; 109 | list_node_insert(&l->l_anchor, &l->l_anchor, &l->l_anchor); 110 | } 111 | 112 | static inline void 113 | list_fini(list_t *l) 114 | { 115 | assert(l->l_anchor.n_prev == &l->l_anchor); 116 | assert(l->l_anchor.n_next == &l->l_anchor); 117 | list_node_delete(&l->l_anchor); 118 | } 119 | 120 | static inline void 121 | list_move(list_t *src, list_t *dst) 122 | { 123 | list_init(dst, src->l_off); 124 | if (src->l_anchor.n_prev != &src->l_anchor) { 125 | list_node_insert(&dst->l_anchor, 126 | src->l_anchor.n_prev, src->l_anchor.n_next); 127 | list_node_insert(&src->l_anchor, 128 | &src->l_anchor, &src->l_anchor); 129 | } 130 | } 131 | 132 | static inline void * 133 | __attribute__((always_inline)) 134 | list_prev(const list_t *l, const void *target) 135 | { 136 | return (list_node_to_data(l, list_node_from_data(l, target)->n_prev)); 137 | } 138 | 139 | static inline void * 140 | __attribute__((always_inline)) 141 | list_next(const list_t *l, const void *target) 142 | { 143 | return (list_node_to_data(l, list_node_from_data(l, target)->n_next)); 144 | } 145 | 146 | static inline void * 147 | __attribute__((always_inline)) 148 | list_head(const list_t *l) 149 | { 150 | return (list_next(l, NULL)); 151 | } 152 | 153 | static inline void * 154 | __attribute__((always_inline)) 155 | list_tail(const list_t *l) 156 | { 157 | return (list_prev(l, NULL)); 158 | } 159 | 160 | static inline void 161 | __attribute__((always_inline)) 162 | list_insert_before(list_t *l, void *before, void *target) 163 | { 164 | list_node_t *t = list_node_from_data(l, target); 165 | list_node_t *n = list_node_from_data(l, before); 166 | list_node_t *p = n->n_prev; 167 | 168 | list_node_insert(t, p, n); 169 | } 170 | 171 | static inline void 172 | __attribute__((always_inline)) 173 | list_insert_after(list_t *l, void *after, void *target) 174 | { 175 | list_node_t *t = list_node_from_data(l, target); 176 | list_node_t *p = list_node_from_data(l, after); 177 | list_node_t *n = p->n_next; 178 | 179 | list_node_insert(t, p, n); 180 | } 181 | 182 | static inline void 183 | __attribute__((always_inline)) 184 | list_insert_head(list_t *l, void *target) 185 | { 186 | list_insert_after(l, NULL, target); 187 | } 188 | 189 | static inline void 190 | __attribute__((always_inline)) 191 | list_insert_tail(list_t *l, void *target) 192 | { 193 | list_insert_before(l, NULL, target); 194 | } 195 | 196 | static inline void 197 | __attribute__((always_inline)) 198 | list_delete(list_t *l, void *target) 199 | { 200 | list_node_delete(list_node_from_data(l, target)); 201 | } 202 | 203 | static inline void * 204 | __attribute__((always_inline)) 205 | list_delete_head(list_t *l) 206 | { 207 | list_node_t *h = list_node_from_data(l, NULL)->n_next; 208 | void *head = list_node_to_data(l, h); 209 | 210 | if (head != NULL) 211 | list_node_delete(h); 212 | 213 | return (head); 214 | } 215 | 216 | static inline void * 217 | __attribute__((always_inline)) 218 | list_delete_tail(list_t *l) 219 | { 220 | list_node_t *t = list_node_from_data(l, NULL)->n_prev; 221 | void *tail = list_node_to_data(l, t); 222 | 223 | if (tail != NULL) 224 | list_node_delete(t); 225 | 226 | return (tail); 227 | } 228 | 229 | #define list_empty(l) (list_head(l) == NULL) 230 | 231 | #ifdef __cplusplus 232 | } 233 | #endif 234 | 235 | #endif /* _LIST_H */ 236 | -------------------------------------------------------------------------------- /lib/libutrace/ut_cc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | static void 31 | utrace_cg_trace(ut_pcb_t *pcb, ut_file_t *file, ut_node_t *f) 32 | { 33 | const ut_var_t *v = f->node_value.l_str->str_vref; 34 | ut_node_t *arg; 35 | 36 | uint8_t ins[8] = { 0 }; 37 | uint8_t i = 0; 38 | 39 | if (f->node_type != UT_TYPE_FUNC) { 40 | yyuterror(&f->node_loc, pcb, "identifier is not a function: %s", 41 | f->node_value.l_str->str_data); 42 | return; 43 | } 44 | 45 | ins[i++] = UT_OPC_ENCODE(v->var_code); 46 | 47 | for (arg = f->node_list; arg != NULL && 48 | i < sizeof (ins); arg = arg->node_link) { 49 | ins[0] = UT_ARG_ENCODE(ins[0], i); 50 | switch (arg->node_token) { 51 | case UT_TOK_INT: 52 | ins[i++] = (uint8_t)arg->node_value.l_int; 53 | break; 54 | default: 55 | ins[i++] = arg->node_value.l_str->str_vref->var_code; 56 | break; 57 | } 58 | } 59 | 60 | if (arg != NULL) { 61 | yyuterror(&arg->node_loc, pcb, "argument limit exceeded: %s", 62 | f->node_value.l_str->str_data); 63 | } 64 | 65 | utrace_file_write(file, UT_FILE_SECT_CODE, ins, sizeof (ins)); 66 | } 67 | 68 | static uint32_t 69 | utrace_cg_probe(ut_pcb_t *pcb, ut_file_t *file, ut_node_t *p) 70 | { 71 | uint32_t n = 0; 72 | ut_file_probe_t pr; 73 | ut_node_t *c; 74 | 75 | for (; p != NULL; p = p->node_link, n++) { 76 | bzero(&pr, sizeof (pr)); 77 | pr.utfp_code = utrace_file_wroff(file, UT_FILE_SECT_CODE); 78 | 79 | for (c = p->node_lhs; c != NULL; c = c->node_link) { 80 | if (c->node_type != c->node_list->node_type) { 81 | yyuterror(&c->node_loc, pcb, "probe parameter " 82 | "type does not match argument type: %s", 83 | c->node_value.l_str->str_data); 84 | continue; 85 | } 86 | 87 | switch (c->node_value.l_str->str_vref->var_code) { 88 | case UT_VAR_EVENT: 89 | pr.utfp_event = utrace_file_wroff( 90 | file, UT_FILE_SECT_STR); 91 | utrace_file_write(file, UT_FILE_SECT_STR, 92 | c->node_list->node_value.l_str->str_data, 93 | c->node_list->node_value.l_str->str_size); 94 | break; 95 | 96 | case UT_VAR_FILE: 97 | pr.utfp_file = utrace_file_wroff( 98 | file, UT_FILE_SECT_STR); 99 | utrace_file_write(file, UT_FILE_SECT_STR, 100 | c->node_list->node_value.l_str->str_data, 101 | c->node_list->node_value.l_str->str_size); 102 | break; 103 | 104 | case UT_VAR_LINE: 105 | pr.utfp_line = c->node_list->node_value.l_int; 106 | break; 107 | 108 | default: 109 | yyuterror(&c->node_loc, pcb, 110 | "invalid probe parameter: %s", 111 | c->node_value.l_str->str_data); 112 | } 113 | } 114 | 115 | for (c = p->node_rhs; c != NULL; c = c->node_link) { 116 | utrace_cg_trace(pcb, file, c); 117 | pr.utfp_clen++; 118 | } 119 | 120 | utrace_file_write(file, UT_FILE_SECT_PROBE, &pr, sizeof (pr)); 121 | } 122 | 123 | return (n); 124 | } 125 | 126 | /* 127 | * Compile the specified input file into an encoded object file. Our entire 128 | * scheme is simple enough that all the passes can be done in one function: 129 | * 130 | * 1. Set up the pcb for sharing state across ut_lex, ut_grammar, and ut_parser. 131 | * 2. yyutparse() to lex and parse the input file and construct the parse tree. 132 | * 3. utrace_node_walk() the parse tree to assign types and resolve identifiers. 133 | * 4. Run cg on the parse tree with no file allocated to determine sizing. 134 | * 5. utrace_file_alloc() to allocate the file and relocate the sections. 135 | * 6. Run on the parse tree again to actually emit the binary object file. 136 | * 7. Wrap up the result object file buffer in a utrace_request_t and return it. 137 | */ 138 | utrace_request_t * 139 | utrace_fcompile(utrace_handle_t *uhp, FILE *fp) 140 | { 141 | utrace_request_t *r = NULL; 142 | ut_pcb_t pcb; 143 | 144 | ut_file_t file; 145 | ut_file_header_t fhdr; 146 | uint32_t prc; 147 | 148 | bzero(&file, sizeof (file)); 149 | utrace_pcb_init(uhp, &pcb, fp); 150 | 151 | if (yyutparse(&pcb) != 0) 152 | goto out; 153 | 154 | if (pcb.pcb_root == NULL) { 155 | (void) utrace_null(uhp, EINVAL, "empty utrace input file"); 156 | pcb.pcb_errs++; 157 | goto out; 158 | } 159 | 160 | if (utrace_node_walk(&pcb, pcb.pcb_root, NULL, NULL) != 0) 161 | goto out; 162 | 163 | utrace_file_write(&file, UT_FILE_SECT_HDR, &fhdr, sizeof (fhdr)); 164 | prc = utrace_cg_probe(&pcb, &file, pcb.pcb_root); 165 | 166 | if (pcb.pcb_errs != 0) 167 | goto out; 168 | 169 | utrace_file_alloc(&file); 170 | bzero(&fhdr, sizeof (fhdr)); 171 | 172 | fhdr.utfh_ident[FHDR_IDENT_MAG0] = FHDR_IDMAG_MAG0; 173 | fhdr.utfh_ident[FHDR_IDENT_MAG1] = FHDR_IDMAG_MAG1; 174 | fhdr.utfh_ident[FHDR_IDENT_MAG2] = FHDR_IDMAG_MAG2; 175 | fhdr.utfh_ident[FHDR_IDENT_MAG3] = FHDR_IDMAG_MAG3; 176 | 177 | fhdr.utfh_wsize = __WORDSIZE; 178 | fhdr.utfh_border = __BYTE_ORDER; 179 | fhdr.utfh_proff = (uint32_t)sizeof (fhdr); 180 | fhdr.utfh_prlen = prc; 181 | 182 | utrace_file_write(&file, UT_FILE_SECT_HDR, &fhdr, sizeof (fhdr)); 183 | (void) utrace_cg_probe(&pcb, &file, pcb.pcb_root); 184 | out: 185 | if (pcb.pcb_errs != 0) { 186 | vmem_free(vmem_heap, file.utfi_data, file.utfi_size); 187 | } else { 188 | r = vmem_alloc(vmem_heap, sizeof (*r), VM_SLEEP); 189 | r->req_buf = file.utfi_data; 190 | r->req_len = file.utfi_size; 191 | } 192 | 193 | utrace_pcb_fini(uhp, &pcb); 194 | return (r); 195 | } 196 | 197 | utrace_request_t * 198 | utrace_compile(utrace_handle_t *uhp, const char *file) 199 | { 200 | utrace_request_t *rp; 201 | FILE *fp; 202 | 203 | if ((fp = fopen(file, "r")) == NULL) 204 | return (utrace_null(uhp, errno, "failed to open %s", file)); 205 | 206 | rp = utrace_fcompile(uhp, fp); 207 | (void) fclose(fp); 208 | return (rp); 209 | } 210 | --------------------------------------------------------------------------------