[build] Address symbol visibility and DSO builds

Added an `API` macro in `j6/api.h` that expands to mark the given
declaration as a default-visible symbol. Also change `format` and
`vformat` to non-template functions, and make calls to `main`, `exit`,
and the library init functions in `_start` GOT-relative.
This commit is contained in:
Justin C. Miller
2023-08-26 19:30:26 -07:00
parent 646a534dfd
commit 8cbde13139
18 changed files with 66 additions and 30 deletions

View File

@@ -8,10 +8,11 @@
#include <stddef.h> #include <stddef.h>
#include <j6/types.h> #include <j6/types.h>
#include <util/api.h>
namespace j6 { namespace j6 {
class channel class API channel
{ {
public: public:
/// Create a new channel of the given size. /// Create a new channel of the given size.

View File

@@ -4,6 +4,7 @@
#include <stdint.h> #include <stdint.h>
#include <j6/types.h> #include <j6/types.h>
#include <util/api.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -71,7 +72,7 @@ struct j6_init_args
/// Find the first handle of the given type held by this process /// Find the first handle of the given type held by this process
j6_handle_t j6_find_first_handle(j6_object_type obj_type); j6_handle_t API j6_find_first_handle(j6_object_type obj_type);
/// Get the init args /// Get the init args
const j6_init_args * j6_get_init_args(); const j6_init_args * j6_get_init_args();

View File

@@ -2,6 +2,7 @@
/// \file memutils.h /// \file memutils.h
/// Standard mem*() library functions /// Standard mem*() library functions
#include <util/api.h>
#include <__j6libc/restrict.h> #include <__j6libc/restrict.h>
#include <__j6libc/size_t.h> #include <__j6libc/size_t.h>
@@ -9,9 +10,9 @@
extern "C" { extern "C" {
#endif #endif
void *memcpy(void * restrict s1, const void * restrict s2, size_t n); void * API memcpy(void * restrict s1, const void * restrict s2, size_t n);
void *memmove(void * restrict s1, const void * restrict s2, size_t n); void * API memmove(void * restrict s1, const void * restrict s2, size_t n);
void *memset(void *s, int c, size_t n); void * API memset(void *s, int c, size_t n);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"

View File

@@ -1,9 +1,10 @@
#include <j6/protocols/service_locator.h> #include <j6/protocols/service_locator.h>
#include <j6/types.h> #include <j6/types.h>
#include <util/api.h>
namespace j6::proto::sl { namespace j6::proto::sl {
class client class API client
{ {
public: public:
/// Constructor. /// Constructor.

View File

@@ -1,9 +1,14 @@
#pragma once
/// \file vfs.hh
/// C++ client interface for VFS protocol
#include <j6/protocols/vfs.h> #include <j6/protocols/vfs.h>
#include <j6/types.h> #include <j6/types.h>
#include <util/api.h>
namespace j6::proto::vfs { namespace j6::proto::vfs {
class client class API client
{ {
public: public:
/// Constructor. /// Constructor.

View File

@@ -10,6 +10,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <util/api.h>
/*[[[cog code generation /*[[[cog code generation
from os.path import join from os.path import join
@@ -35,7 +36,7 @@ enum j6_sysconf_arg
/// Get the kernel configuration value specified by /// Get the kernel configuration value specified by
/// the argument. /// the argument.
unsigned long j6_sysconf(j6_sysconf_arg arg); unsigned long API j6_sysconf(j6_sysconf_arg arg);
#ifdef __cplusplus #ifdef __cplusplus
} // extern C } // extern C

View File

@@ -2,13 +2,15 @@
/// \file j6/syslog.hh /// \file j6/syslog.hh
/// Utility function for writing messages to the kernel log /// Utility function for writing messages to the kernel log
#include <util/api.h>
// The kernel depends on libj6 for some shared code, // The kernel depends on libj6 for some shared code,
// but should not include the user-specific code. // but should not include the user-specific code.
#ifndef __j6kernel #ifndef __j6kernel
namespace j6 { namespace j6 {
void syslog(const char *fmt, ...); void API syslog(const char *fmt, ...);
} // namespace j6 } // namespace j6

View File

@@ -36,13 +36,13 @@ j6_find_first_handle(j6_object_type obj_type)
return j6_handle_invalid; return j6_handle_invalid;
} }
const j6_init_args * const j6_init_args * API
j6_get_init_args() j6_get_init_args()
{ {
return &init_args; return &init_args;
} }
extern "C" void extern "C" void API
__init_libj6(uint64_t arg0, uint64_t arg1) __init_libj6(uint64_t arg0, uint64_t arg1)
{ {
init_args.args[0] = arg0; init_args.args[0] = arg0;

View File

@@ -4,6 +4,7 @@
#include <util/format.h> #include <util/format.h>
#include <j6/syscalls.h> #include <j6/syscalls.h>
#include <j6/syslog.hh>
namespace j6 { namespace j6 {

View File

@@ -12,17 +12,17 @@ _libc_crt0_start:
push 0 push 0
mov rbp, rsp mov rbp, rsp
call __init_libj6 call __init_libj6 wrt ..got
mov rbx, rax mov rbx, rax
call __init_libc call __init_libc wrt ..got
mov rdi, 0 mov rdi, 0
mov rsi, rsp mov rsi, rsp
mov rdx, 0 ; TODO: actually parse stack for argc, argv, envp mov rdx, 0 ; TODO: actually parse stack for argc, argv, envp
mov rcx, rbx mov rcx, rbx
call main call main wrt ..got
mov rdi, rax mov rdi, rax
call exit call exit wrt ..got
.end: .end:

View File

@@ -27,7 +27,7 @@ for ext in ("h",):
libc = module("libc", libc = module("libc",
kind = "lib", kind = "lib",
deps = [ "j6" ], deps = [ "j6" ],
output = "libc.a", basename = "libc",
include_phase = "late", include_phase = "late",
sources = sources, sources = sources,
public_headers = headers, public_headers = headers,
@@ -35,6 +35,7 @@ libc = module("libc",
libc.variables["ccflags"] = [ libc.variables["ccflags"] = [
"${ccflags}", "${ccflags}",
"-fvisibility=default",
"-DPRINTF_SUPPORT_DECIMAL_SPECIFIERS=0", "-DPRINTF_SUPPORT_DECIMAL_SPECIFIERS=0",
"-DPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS=0", "-DPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS=0",
] ]

View File

@@ -88,7 +88,6 @@ append_string(char_t *&out, size_t &count, size_t max, unsigned width, char_t co
} }
} }
} // namespace
template <typename char_t> size_t template <typename char_t> size_t
vformat(counted<char_t> output, char_t const *format, va_list va) vformat(counted<char_t> output, char_t const *format, va_list va)
@@ -169,20 +168,28 @@ vformat(counted<char_t> output, char_t const *format, va_list va)
return count; return count;
} }
template <typename char_t> size_t } // namespace
format(counted<char_t> output, const char_t *format, ...)
size_t API format(counted<char> output, const char *format, ...)
{ {
va_list va; va_list va;
va_start(va, format); va_start(va, format);
size_t result = vformat<char_t>(output, format, va); size_t result = vformat<char>(output, format, va);
va_end(va); va_end(va);
return result; return result;
} }
template size_t format<char>(counted<char> output, const char *format, ...); size_t API format(counted<wchar_t> output, const wchar_t *format, ...)
template size_t vformat<char>(counted<char> output, const char *format, va_list va); {
va_list va;
va_start(va, format);
size_t result = vformat<wchar_t>(output, format, va);
va_end(va);
return result;
}
size_t API vformat(counted<char> output, const char *format, va_list va) { return vformat<char>(output, format, va); }
size_t API vformat(counted<wchar_t> output, const wchar_t *format, va_list va) { return vformat<wchar_t>(output, format, va); }
template size_t format<wchar_t>(counted<wchar_t> output, const wchar_t *format, ...);
template size_t vformat<wchar_t>(counted<wchar_t> output, const wchar_t *format, va_list va);
} //namespace util } //namespace util

View File

@@ -2,6 +2,9 @@
/// \file allocator.h /// \file allocator.h
/// Definition of the allocator interface. /// Definition of the allocator interface.
#include <stddef.h>
#include <j6/memutils.h>
namespace util { namespace util {
// Allocators are types with three static methods with these signatures // Allocators are types with three static methods with these signatures

View File

@@ -0,0 +1,7 @@
#pragma once
/// \file api.h
/// Library interface visibility macros
#ifndef API
#define API __attribute__ ((visibility ("default")))
#endif

View File

@@ -6,11 +6,12 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <util/api.h>
#include <util/spinlock.h> #include <util/spinlock.h>
namespace util { namespace util {
class bip_buffer class API bip_buffer
{ {
public: public:
/// Default constructor. Creates a zero-size buffer. /// Default constructor. Creates a zero-size buffer.

View File

@@ -4,14 +4,16 @@
#pragma once #pragma once
#include <stdarg.h> #include <stdarg.h>
#include <util/api.h>
#include <util/counted.h> #include <util/counted.h>
namespace util { namespace util {
template <typename char_t> size_t API format(counted<char> output, const char *format, ...);
size_t format(counted<char_t> output, const char_t *format, ...); size_t API vformat(counted<char> output, const char *format, va_list va);
template <typename char_t>
size_t vformat(counted<char_t> output, const char_t *format, va_list va); size_t API format(counted<wchar_t> output, const wchar_t *format, ...);
size_t API vformat(counted<wchar_t> output, const wchar_t *format, va_list va);
} }

View File

@@ -3,6 +3,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <util/api.h>
#ifdef __j6kernel #ifdef __j6kernel
extern "C" uint32_t __current_thread_id(); extern "C" uint32_t __current_thread_id();
@@ -11,7 +12,7 @@ extern "C" uint32_t __current_thread_id();
namespace util { namespace util {
/// An MCS based spinlock /// An MCS based spinlock
class spinlock class API spinlock
{ {
public: public:
spinlock(); spinlock();

View File

@@ -10,6 +10,7 @@ module("util",
], ],
public_headers = [ public_headers = [
"util/allocator.h", "util/allocator.h",
"util/api.h",
"util/assert.h", "util/assert.h",
"util/basic_types.h", "util/basic_types.h",
"util/bip_buffer.h", "util/bip_buffer.h",