[osv-dev] [PATCH] sysconf: handle _SC_MINSIGSTKSZ and _SC_SIGSTKSZ

2022-05-11 Thread Waldemar Kozaczuk
New versions (>= ~1.74) of boost unit test library used by some of our
tests started using sysconf() with argument _SC_SIGSTKSZ to determine
size of the signal stack size.

This patch enhances the sysconf() implementation to handle _SC_MINSIGSTKSZ
and _SC_SIGSTKSZ.

Signed-off-by: Waldemar Kozaczuk 
---
 include/api/unistd.h | 2 ++
 runtime.cc   | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/include/api/unistd.h b/include/api/unistd.h
index 4cf86adb..cb5f4489 100644
--- a/include/api/unistd.h
+++ b/include/api/unistd.h
@@ -470,6 +470,8 @@ void syncfs(int);
 #define _SC_XOPEN_STREAMS  246
 #define _SC_THREAD_ROBUST_PRIO_INHERIT 247
 #define _SC_THREAD_ROBUST_PRIO_PROTECT 248
+#define _SC_MINSIGSTKSZ 249
+#define _SC_SIGSTKSZ 250
 
 #define _CS_PATH   0
 #define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1
diff --git a/runtime.cc b/runtime.cc
index 3942982c..521b5c24 100644
--- a/runtime.cc
+++ b/runtime.cc
@@ -379,6 +379,8 @@ long sysconf(int name)
 case _SC_THREAD_SAFE_FUNCTIONS: return 1;
 case _SC_GETGR_R_SIZE_MAX: return 1;
 case _SC_OPEN_MAX: return FDMAX;
+case _SC_MINSIGSTKSZ: return MINSIGSTKSZ;
+case _SC_SIGSTKSZ: return SIGSTKSZ;
 default:
 debug(fmt("sysconf(): stubbed for parameter %1%\n") % name);
 errno = EINVAL;
-- 
2.34.1

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/20220511215346.84070-1-jwkozaczuk%40gmail.com.


[osv-dev] [PATCH] tests: detect boost setup errors

2022-05-11 Thread Waldemar Kozaczuk
New boost (>= ~1.74) based unit tests started using sysconf()
to determine signal stack size which at this moment is not supported
by OSv implementation. These results in errors looking like this:

"Test setup error: std::bad_alloc: std::bad_alloc"

which are happily ignored by our error pattern detection logic
in testing.py. This patch adds one more failure pattern.

Signed-off-by: Waldemar Kozaczuk 
---
 scripts/tests/testing.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/tests/testing.py b/scripts/tests/testing.py
index a1cdec35..50b49c08 100644
--- a/scripts/tests/testing.py
+++ b/scripts/tests/testing.py
@@ -81,7 +81,8 @@ def scan_errors(s,scan_for_failed_to_load_object_error=True):
 "at org.junit.runner.JUnitCore.main",
 "ContextFailedException",
 "AppThreadTerminatedWithUncaughtException",
-   "\[backtrace\]"
+   "\[backtrace\]",
+"Test setup error"
 ]
 
 if scan_for_failed_to_load_object_error:
-- 
2.35.1

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/20220511214915.143995-1-jwkozaczuk%40gmail.com.


[osv-dev] [PATCH] libc: implement _dl_find_object()

2022-05-11 Thread Waldemar Kozaczuk
Ubuntu 2022.04 comes with a new version of GCC 11.2.0 that
somehow includes instance of libgcc_s.so.1 destined for GCC_12.0.0
at least based on what readelf shows. The implication of this is
that during exception handling and stack unwinding, this version
of libgcc_so.so.1 uses _dl_find_object() function what was
very recently added to glibc. For more details please read
following:
- https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg275982.html
- https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg273082.html
- 
https://github.com/gcc-mirror/gcc/commit/790854ea7670f11c14d431c102a49181d2915965
- 
http://www.gnu.org/software/libc/manual/html_node/Dynamic-Linker-Introspection.html

So this patch adds basic (a little incomplete) implementation of 
_dl_find_object()
that can satisfy the need of new libgcc_s.so.1 - field dlfo_eh_frame of the 
struct
dl_find_object. Please note that for now we do not populate the dlfo_link_map 
field
as it is not clear what exactly goes it there and how it is used. We may need to
revisit this later.

Signed-off-by: Waldemar Kozaczuk 
---
 exported_symbols/osv_libc.so.6.symbols |  1 +
 include/api/__dlfcn.h  | 26 ++
 libc/dlfcn.cc  | 20 
 3 files changed, 47 insertions(+)
 create mode 100644 include/api/__dlfcn.h

diff --git a/exported_symbols/osv_libc.so.6.symbols 
b/exported_symbols/osv_libc.so.6.symbols
index 7bae56c4..7ae57c38 100644
--- a/exported_symbols/osv_libc.so.6.symbols
+++ b/exported_symbols/osv_libc.so.6.symbols
@@ -86,6 +86,7 @@ dirfd
 dirname
 div
 dl_iterate_phdr
+_dl_find_object
 dngettext
 dprintf
 drand48
diff --git a/include/api/__dlfcn.h b/include/api/__dlfcn.h
new file mode 100644
index ..228122d1
--- /dev/null
+++ b/include/api/__dlfcn.h
@@ -0,0 +1,26 @@
+#ifndef___DLFCN_H
+#define___DLFCN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dl_find_object
+{
+  __extension__ unsigned long long int dlfo_flags;
+  void *dlfo_map_start;/* Beginning of mapping containing 
address.  */
+  void *dlfo_map_end;  /* End of mapping.  */
+  struct link_map *dlfo_link_map;
+  void *dlfo_eh_frame; /* Exception handling data of the object.  */
+  __extension__ unsigned long long int __dflo_reserved[7];
+};
+
+/* If ADDRESS is found in an object, fill in *RESULT and return 0.
+   Otherwise, return -1.  */
+int _dl_find_object (void *__address, struct dl_find_object *__result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libc/dlfcn.cc b/libc/dlfcn.cc
index fa496e4e..8ec37148 100644
--- a/libc/dlfcn.cc
+++ b/libc/dlfcn.cc
@@ -6,6 +6,7 @@
  */
 
 #include 
+#include <__dlfcn.h>
 #include 
 #include 
 #include 
@@ -142,3 +143,22 @@ extern "C" char *dlerror(void)
 {
 return dlerror_set(nullptr);
 }
+
+extern "C" int _dl_find_object(void *address, dl_find_object* result)
+{   //
+// Find ELF object with a mapping containing the passed in
+// address and if found populate the result structure as described
+// in 
http://www.gnu.org/software/libc/manual/html_node/Dynamic-Linker-Introspection.html
+auto eo = elf::get_program()->object_containing_addr(address);
+if (eo) {
+result->dlfo_map_start = eo->base();
+result->dlfo_map_end = eo->end();
+result->dlfo_eh_frame = eo->eh_frame_addr();
+//TODO: For now we are neglecting to populate the 
result->dlfo_link_map field
+//as it is not very well documented what exactly should go there. 
Eventually,
+//once we understand the purpose of this field better, we should 
populate it as well.
+  return 0;
+   } else {
+  return -1;
+   }
+}
-- 
2.34.1

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/20220511194936.46011-1-jwkozaczuk%40gmail.com.


[osv-dev] [PATCH] elf: capture address of PT_GNU_EH_FRAME

2022-05-11 Thread Waldemar Kozaczuk
Signed-off-by: Waldemar Kozaczuk 
---
 core/elf.cc| 5 -
 include/osv/elf.hh | 2 ++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/core/elf.cc b/core/elf.cc
index 5170bf53..c96a45ec 100644
--- a/core/elf.cc
+++ b/core/elf.cc
@@ -124,6 +124,7 @@ object::object(program& prog, std::string pathname)
 , _module_index(_prog.register_dtv(this))
 , _is_executable(false)
 , _init_called(false)
+, _eh_frame(0)
 , _visibility_thread(nullptr)
 , _visibility_level(VisibilityLevel::Public)
 {
@@ -517,10 +518,12 @@ void object::process_headers()
 case PT_PHDR:
 case PT_GNU_STACK:
 case PT_GNU_RELRO:
-case PT_GNU_EH_FRAME:
 case PT_PAX_FLAGS:
 case PT_GNU_PROPERTY:
 break;
+case PT_GNU_EH_FRAME:
+_eh_frame = _base + phdr.p_vaddr;
+break;
 case PT_TLS:
 _tls_segment = _base + phdr.p_vaddr;
 _tls_init_size = phdr.p_filesz;
diff --git a/include/osv/elf.hh b/include/osv/elf.hh
index afc9c9a5..31702bf8 100644
--- a/include/osv/elf.hh
+++ b/include/osv/elf.hh
@@ -383,6 +383,7 @@ public:
 ulong get_tls_size();
 ulong get_aligned_tls_size();
 void copy_local_tls(void* to_addr);
+void* eh_frame_addr() { return _eh_frame; }
 protected:
 virtual void load_segment(const Elf64_Phdr& segment) = 0;
 virtual void unload_segment(const Elf64_Phdr& segment) = 0;
@@ -436,6 +437,7 @@ protected:
 bool _is_executable;
 bool is_core();
 bool _init_called;
+void* _eh_frame;
 
 std::unordered_map _cached_symbols;
 
-- 
2.34.1

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/20220511141000.37478-1-jwkozaczuk%40gmail.com.


[osv-dev] [COMMIT osv master] scripts: expand %(libgcc_s_dir) when generating usr.manifest

2022-05-11 Thread Commit Bot
From: Waldemar Kozaczuk 
Committer: Nadav Har'El 
Branch: master

scripts: expand %(libgcc_s_dir) when generating usr.manifest

The manifest skeleton files like usr.manifest.skel have an entry
for libgcc_s_dir looking like this:

/usr/lib/libgcc_s.so.1: %(libgcc_s_dir)s/libgcc_s.so.1

This actually gets expanded quite late during the build process
by upload_manifest.py. The unfortunate consequence of this is that
loader.py used during debugging which reads usr.manifest does not have
any logic to load libgcc_s.so.1. And this makes stack traces
look useless in those cases that involve libgcc_s.so.1.

So this patch slightly changes the scripts/build and scripts/module.py
to expand %(libgcc_s_dir) when writing to build/release/usr.manifest.
As a result of this the stack trace of the crash I have been working
on looks much more reasonable:

(gdb) bt
'#0  0x403047c2 in processor::cli_hlt () at arch/x64/processor.hh:247
#1  arch::halt_no_interrupts () at arch/x64/arch.hh:48
#2  osv::halt () at arch/x64/power.cc:29
#3  0x40239504 in abort (fmt=fmt@entry=0x405b1e93 "Aborted\n") at 
runtime.cc:142
#4  0x40202e80 in abort () at runtime.cc:106
#5  0x1002b6b6 in ?? ()
#6  0x1003f5cb in _Unwind_Resume ()
#7  0x10062daa in ?? ()
#8  0x10075b5c in 
boost::execution_monitor::vexecute(boost::function const&) ()
#9  0x1007f0a9 in boost::unit_test::framework::init(bool (*)(), int, 
char**) ()
#10 0x1009254d in boost::unit_test::unit_test_main(bool (*)(), int, 
char**) ()
#11 0x4039d021 in osv::application::run_main (this=0xa0bd8c10) 
at core/app.cc:416
#12 0x4039d22d in operator() (app=, __closure=0x0) at 
core/app.cc:236
#13 _FUN () at core/app.cc:238
#14 0x403d089a in operator() (__closure=0xa0d57800) at 
libc/pthread.cc:116
#15 std::__invoke_impl&> 
(__f=...) at /usr/include/c++/11/bits/invoke.h:61
#16 std::__invoke_r&> (__fn=...) 
at /usr/include/c++/11/bits/invoke.h:154
#17 std::_Function_handler 
>::_M_invoke(const std::_Any_data &) (__functor=...) at 
/usr/include/c++/11/bits/std_function.h:290
#18 0x4036b5ae in sched::thread::main (this=0x80f6a040) at 
core/sched.cc:1267
#19 sched::thread_main_c (t=0x80f6a040) at arch/x64/arch-switch.hh:325
#20 0x402fda43 in thread_main () at arch/x64/entry.S:116

Signed-off-by: Waldemar Kozaczuk 
Message-Id: <20220511015843.33294-1-jwkozac...@gmail.com>

---
diff --git a/scripts/build b/scripts/build
--- a/scripts/build
+++ b/scripts/build
@@ -227,6 +227,21 @@ if [[ ${vars[append_manifest]} == "true" && $modules == 
"!default" ]]; then
modules="empty"
 fi
 
+CC=gcc
+if [[ "$host_arch" == "x86_64" && "$arch" == 'aarch64' ]]; then
+CC=${CROSS_PREFIX:-aarch64-linux-gnu-}gcc
+fi
+
+libgcc_s_path=$(${CC} -print-file-name=libgcc_s.so.1)
+if [[ "$libgcc_s_path" == "libgcc_s.so.1" ]]; then
+   cat <<-EOF
+   Unable to resolve libgcc_s.so.1 using "${CC}".
+   Looking in build/downloaded_packages/aarch64/gcc/install/lib64
+   EOF
+   
libgcc_s_path="build/downloaded_packages/aarch64/gcc/install/lib64/libgcc_s.so.1"
+fi
+libgcc_s_dir=$(dirname $(readlink -f ${libgcc_s_path}))
+
 # The parentheses start a subshell. Whatever is exported there, doesn't affect 
the external shell
 (
# Note: the double-quotes and almost everything in the line below is 
important to correctly allow spaces
@@ -240,7 +255,7 @@ fi
esac
done
# Export the variables we already have. This makes it unnecessary to do 
"fs__type=$fstype ..."
-   export fs_type mode OSV_BUILD_PATH
+   export fs_type mode OSV_BUILD_PATH libgcc_s_dir
# Other variables we wanted to rename, I don't know why
export ARCH=$arch OSV_BASE=$SRC
# Run what we wanted to run. It will inherit everything we exported 
above.
@@ -276,21 +291,6 @@ kernel_end=$(($loader_size+2097151 & ~2097151))
 # the case in our old build.mk).
 cd $OUT
 
-CC=gcc
-if [[ "$host_arch" == "x86_64" && "$arch" == 'aarch64' ]]; then
-CC=${CROSS_PREFIX:-aarch64-linux-gnu-}gcc
-fi
-
-libgcc_s_path=$(${CC} -print-file-name=libgcc_s.so.1)
-if [[ "$libgcc_s_path" == "libgcc_s.so.1" ]]; then
-   cat <<-EOF
-   Unable to resolve libgcc_s.so.1 using "${CC}".
-   Looking in ../downloaded_packages/aarch64/gcc/install/lib64
-   EOF
-   
libgcc_s_path="../downloaded_packages/aarch64/gcc/install/lib64/libgcc_s.so.1"
-fi
-libgcc_s_dir=$(dirname $(readlink -f ${libgcc_s_path}))
-
 if [ "$export" != "none" ]; then
export_dir=${vars[export_dir]-$SRC/build/export}
"$SRC"/scripts/export_manifest.py -e "$export_dir" -m usr.manifest -D 
libgcc_s_dir="$libgcc_s_dir"
diff --git a/scripts/module.py b/scripts/module.py
--- a/scripts/module.py
+++ b/scripts/module.py
@@ -57,12 +57,15 @@ def resolve(m):
 
 return re.sub(r'\${(?P.*)}', resolve, text)
 
-def append_manifest(file_path, dst_file, variables={}):
+def