commit bc66028c74e6c565488300fd72ba18d3718c3055
parent 556472c785d8cf94ad8f9f5c376ad127b39975d4
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Mon, 25 May 2026 13:28:08 -0700
build: hide non-public libcfree symbols
Diffstat:
19 files changed, 306 insertions(+), 304 deletions(-)
diff --git a/Makefile b/Makefile
@@ -61,7 +61,8 @@ FREESTANDING_CFLAGS = $(CFLAGS_COMMON) $(FREESTANDING_CONFIG_CFLAGS) -ffreestand
# libcfree: written in C11 freestanding; sees both src/ (internal) and
# include/ (its own public surface).
-LIB_CFLAGS = $(FREESTANDING_CFLAGS) -Iinclude -Isrc
+LIB_VISIBILITY_CFLAGS = -fvisibility=hidden
+LIB_CFLAGS = $(FREESTANDING_CFLAGS) $(LIB_VISIBILITY_CFLAGS) -Iinclude -Isrc
# Driver: mostly freestanding CLI binary. Sees only the public include/ tree —
# that's what makes the driver the first consumer of libcfree. -Ilang lets `cc`
@@ -239,18 +240,18 @@ $(BUILD_DIR)/lib/api/lang_registry.o: src/api/lang_registry.c Makefile $(BUILD_C
$(BUILD_DIR)/lang/cpp/%.o: lang/cpp/%.c Makefile $(BUILD_CONFIG)
@mkdir -p $(dir $@)
- $(CC) $(FREESTANDING_CFLAGS) -Iinclude -Ilang/cpp $(DEPFLAGS) -c $< -o $@
+ $(CC) $(FREESTANDING_CFLAGS) $(LIB_VISIBILITY_CFLAGS) -Iinclude -Ilang/cpp $(DEPFLAGS) -c $< -o $@
# The C frontend includes the lexer and preprocessor headers (pp/pp.h,
# lex/lex.h) which now live under lang/cpp/, and cpp_support.h is the
# shared substrate. So lang/c objects build with -Ilang/cpp -Ilang/c.
$(BUILD_DIR)/lang/c/%.o: lang/c/%.c Makefile $(BUILD_CONFIG)
@mkdir -p $(dir $@)
- $(CC) $(FREESTANDING_CFLAGS) -Iinclude -Ilang/cpp -Ilang/c $(DEPFLAGS) -c $< -o $@
+ $(CC) $(FREESTANDING_CFLAGS) $(LIB_VISIBILITY_CFLAGS) -Iinclude -Ilang/cpp -Ilang/c $(DEPFLAGS) -c $< -o $@
$(BUILD_DIR)/lang/wasm/%.o: lang/wasm/%.c Makefile $(BUILD_CONFIG)
@mkdir -p $(dir $@)
- $(CC) $(FREESTANDING_CFLAGS) -Iinclude -Ilang/wasm $(DEPFLAGS) -c $< -o $@
+ $(CC) $(FREESTANDING_CFLAGS) $(LIB_VISIBILITY_CFLAGS) -Iinclude -Ilang/wasm $(DEPFLAGS) -c $< -o $@
$(BUILD_DIR)/lib/%.o: src/%.S Makefile $(BUILD_CONFIG)
@mkdir -p $(dir $@)
@@ -266,7 +267,7 @@ $(BUILD_DIR)/driver/env.o: driver/env.c Makefile $(BUILD_CONFIG)
$(BUILD_DIR)/lang/toy/%.o: lang/toy/%.c Makefile $(BUILD_CONFIG)
@mkdir -p $(dir $@)
- $(CC) $(FREESTANDING_CFLAGS) -Iinclude -Ilang/toy $(DEPFLAGS) -c $< -o $@
+ $(CC) $(FREESTANDING_CFLAGS) $(LIB_VISIBILITY_CFLAGS) -Iinclude -Ilang/toy $(DEPFLAGS) -c $< -o $@
include rt/Makefile
diff --git a/include/cfree/arch.h b/include/cfree/arch.h
@@ -19,11 +19,11 @@ typedef struct CfreeArchReg {
CfreeSlice name;
} CfreeArchReg;
-CfreeSlice cfree_arch_register_name(CfreeArchKind, uint32_t dwarf_idx);
-CfreeStatus cfree_arch_register_index(CfreeArchKind, CfreeSlice name,
+CFREE_API CfreeSlice cfree_arch_register_name(CfreeArchKind, uint32_t dwarf_idx);
+CFREE_API CfreeStatus cfree_arch_register_index(CfreeArchKind, CfreeSlice name,
uint32_t *idx_out);
-uint32_t cfree_arch_register_count(CfreeArchKind);
-CfreeStatus cfree_arch_register_at(CfreeArchKind, uint32_t idx,
+CFREE_API uint32_t cfree_arch_register_count(CfreeArchKind);
+CFREE_API CfreeStatus cfree_arch_register_at(CfreeArchKind, uint32_t idx,
CfreeArchReg *out);
#endif
diff --git a/include/cfree/archive.h b/include/cfree/archive.h
@@ -29,10 +29,10 @@ typedef struct CfreeArInput {
CfreeSlice bytes;
} CfreeArInput;
-CfreeStatus cfree_ar_write(CfreeWriter *out, const CfreeArInput *members,
+CFREE_API CfreeStatus cfree_ar_write(CfreeWriter *out, const CfreeArInput *members,
uint32_t nmembers,
const CfreeArWriteOptions *opts);
-CfreeStatus cfree_ar_list(const CfreeSlice *archive, CfreeWriter *out);
+CFREE_API CfreeStatus cfree_ar_list(const CfreeSlice *archive, CfreeWriter *out);
typedef struct CfreeArIter CfreeArIter;
@@ -42,9 +42,9 @@ typedef struct CfreeArMember {
size_t size;
} CfreeArMember;
-CfreeStatus cfree_ar_iter_new(const CfreeContext *, const CfreeSlice *archive,
+CFREE_API CfreeStatus cfree_ar_iter_new(const CfreeContext *, const CfreeSlice *archive,
CfreeArIter **out);
-CfreeIterResult cfree_ar_iter_next(CfreeArIter *, CfreeArMember *out);
-void cfree_ar_iter_free(CfreeArIter *);
+CFREE_API CfreeIterResult cfree_ar_iter_next(CfreeArIter *, CfreeArMember *out);
+CFREE_API void cfree_ar_iter_free(CfreeArIter *);
#endif
diff --git a/include/cfree/asm_emit.h b/include/cfree/asm_emit.h
@@ -4,6 +4,6 @@
#include <cfree/core.h>
#include <cfree/object.h>
-CfreeStatus cfree_obj_builder_emit_asm(CfreeObjBuilder *, CfreeWriter *);
+CFREE_API CfreeStatus cfree_obj_builder_emit_asm(CfreeObjBuilder *, CfreeWriter *);
#endif
diff --git a/include/cfree/cg.h b/include/cfree/cg.h
@@ -143,51 +143,51 @@ typedef struct CfreeCgRecordDesc {
*
* Integer types are width-only storage types. Signedness is carried by
* operations, comparisons, conversions, and ABI extension attributes. */
-CfreeCgBuiltinTypes cfree_cg_builtin_types(CfreeCompiler*);
+CFREE_API CfreeCgBuiltinTypes cfree_cg_builtin_types(CfreeCompiler*);
/* Interned structural types. Address space 0 is the normal target data
* address space. */
-CfreeCgTypeId cfree_cg_type_func(CfreeCompiler*, CfreeCgFuncSig sig);
-CfreeCgTypeId cfree_cg_type_ptr(CfreeCompiler*, CfreeCgTypeId pointee,
+CFREE_API CfreeCgTypeId cfree_cg_type_func(CfreeCompiler*, CfreeCgFuncSig sig);
+CFREE_API CfreeCgTypeId cfree_cg_type_ptr(CfreeCompiler*, CfreeCgTypeId pointee,
uint32_t address_space);
-CfreeCgTypeId cfree_cg_type_array(CfreeCompiler*, CfreeCgTypeId elem,
+CFREE_API CfreeCgTypeId cfree_cg_type_array(CfreeCompiler*, CfreeCgTypeId elem,
uint64_t count);
/* Fresh nominal/source-facing types. Enums use a width-only integer base. */
-CfreeCgTypeId cfree_cg_type_alias(CfreeCompiler*, CfreeSym name,
+CFREE_API CfreeCgTypeId cfree_cg_type_alias(CfreeCompiler*, CfreeSym name,
CfreeCgTypeId base);
-CfreeCgTypeId cfree_cg_type_record(CfreeCompiler*, CfreeSym tag,
+CFREE_API CfreeCgTypeId cfree_cg_type_record(CfreeCompiler*, CfreeSym tag,
const CfreeCgField* fields,
uint32_t nfields);
-CfreeCgTypeId cfree_cg_type_record_ex(CfreeCompiler*, const CfreeCgRecordDesc*);
-CfreeCgTypeId cfree_cg_type_enum(CfreeCompiler*, CfreeSym tag,
+CFREE_API CfreeCgTypeId cfree_cg_type_record_ex(CfreeCompiler*, const CfreeCgRecordDesc*);
+CFREE_API CfreeCgTypeId cfree_cg_type_enum(CfreeCompiler*, CfreeSym tag,
CfreeCgTypeId base,
const CfreeCgEnumValue* values,
uint32_t nvalues);
/* Type queries. These report codegen storage, ABI, and target layout facts. */
-CfreeCgTypeKind cfree_cg_type_kind(CfreeCompiler*, CfreeCgTypeId);
-uint64_t cfree_cg_type_size(CfreeCompiler*, CfreeCgTypeId);
-uint32_t cfree_cg_type_align(CfreeCompiler*, CfreeCgTypeId);
-uint32_t cfree_cg_type_int_width(CfreeCompiler*, CfreeCgTypeId);
-uint32_t cfree_cg_type_float_width(CfreeCompiler*, CfreeCgTypeId);
-
-CfreeCgTypeId cfree_cg_type_ptr_pointee(CfreeCompiler*, CfreeCgTypeId);
-uint32_t cfree_cg_type_ptr_address_space(CfreeCompiler*, CfreeCgTypeId);
-CfreeCgTypeId cfree_cg_type_array_elem(CfreeCompiler*, CfreeCgTypeId);
-uint64_t cfree_cg_type_array_count(CfreeCompiler*, CfreeCgTypeId);
-
-CfreeCgTypeId cfree_cg_type_func_ret(CfreeCompiler*, CfreeCgTypeId);
-CfreeCgAbiAttrs cfree_cg_type_func_ret_attrs(CfreeCompiler*, CfreeCgTypeId);
-uint32_t cfree_cg_type_func_nparams(CfreeCompiler*, CfreeCgTypeId);
-CfreeCgFuncParam cfree_cg_type_func_param(CfreeCompiler*, CfreeCgTypeId,
+CFREE_API CfreeCgTypeKind cfree_cg_type_kind(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API uint64_t cfree_cg_type_size(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API uint32_t cfree_cg_type_align(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API uint32_t cfree_cg_type_int_width(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API uint32_t cfree_cg_type_float_width(CfreeCompiler*, CfreeCgTypeId);
+
+CFREE_API CfreeCgTypeId cfree_cg_type_ptr_pointee(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API uint32_t cfree_cg_type_ptr_address_space(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API CfreeCgTypeId cfree_cg_type_array_elem(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API uint64_t cfree_cg_type_array_count(CfreeCompiler*, CfreeCgTypeId);
+
+CFREE_API CfreeCgTypeId cfree_cg_type_func_ret(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API CfreeCgAbiAttrs cfree_cg_type_func_ret_attrs(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API uint32_t cfree_cg_type_func_nparams(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API CfreeCgFuncParam cfree_cg_type_func_param(CfreeCompiler*, CfreeCgTypeId,
uint32_t index);
-CfreeCgCallConv cfree_cg_type_func_call_conv(CfreeCompiler*, CfreeCgTypeId);
-int cfree_cg_type_func_is_variadic(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API CfreeCgCallConv cfree_cg_type_func_call_conv(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API int cfree_cg_type_func_is_variadic(CfreeCompiler*, CfreeCgTypeId);
-uint32_t cfree_cg_type_record_nfields(CfreeCompiler*, CfreeCgTypeId);
+CFREE_API uint32_t cfree_cg_type_record_nfields(CfreeCompiler*, CfreeCgTypeId);
/* Returns CFREE_OK and fills any non-NULL out parameters on success. */
-CfreeStatus cfree_cg_type_record_field(CfreeCompiler*, CfreeCgTypeId,
+CFREE_API CfreeStatus cfree_cg_type_record_field(CfreeCompiler*, CfreeCgTypeId,
uint32_t index, CfreeCgField* out,
uint64_t* offset_out);
@@ -219,10 +219,10 @@ typedef enum CfreeCgBackendFeatureFlag {
* requested feature correctly, not whether it is fast. These are target
* facts, not knobs: frontends use them to choose a legal lowering or to emit
* an unsupported-feature diagnostic before asking CG to produce output. */
-int cfree_cg_target_supports_call_conv(CfreeCompiler*, CfreeCgCallConv);
-int cfree_cg_target_supports_symbol_feature(CfreeCompiler*,
+CFREE_API int cfree_cg_target_supports_call_conv(CfreeCompiler*, CfreeCgCallConv);
+CFREE_API int cfree_cg_target_supports_symbol_feature(CfreeCompiler*,
CfreeCgSymbolFeature);
-uint64_t cfree_cg_target_backend_features(CfreeCompiler*);
+CFREE_API uint64_t cfree_cg_target_backend_features(CfreeCompiler*);
/* ============================================================
* Memory Access
@@ -382,10 +382,10 @@ typedef struct CfreeCgAlias {
* Undefined weak references are ordinary declarations with sym.bind =
* CFREE_SB_WEAK and no definition. Weak aliases are aliases whose attrs bind
* is CFREE_SB_WEAK. */
-CfreeCgSym cfree_cg_decl(CfreeCg*, CfreeCgDecl decl);
+CFREE_API CfreeCgSym cfree_cg_decl(CfreeCg*, CfreeCgDecl decl);
/* Defines alias.linkage_name as another symbol for alias.target. */
-CfreeCgSym cfree_cg_alias(CfreeCg*, CfreeCgAlias alias);
+CFREE_API CfreeCgSym cfree_cg_alias(CfreeCg*, CfreeCgAlias alias);
/* Converts a source-level C ABI symbol spelling to the exact object/linker
* spelling for the selected target. This is object-format decoration only
@@ -393,30 +393,30 @@ CfreeCgSym cfree_cg_alias(CfreeCg*, CfreeCgAlias alias);
* remains the frontend's responsibility. Use this when filling
* CfreeCgDecl.linkage_name for symbols that should interoperate with C entry
* names, libc symbols, and linker entry lookup. */
-CfreeSym cfree_cg_c_linkage_name(CfreeCompiler*, CfreeSym source_name);
+CFREE_API CfreeSym cfree_cg_c_linkage_name(CfreeCompiler*, CfreeSym source_name);
/* ============================================================
* Lifecycle and Source Locations
* ============================================================ */
-CfreeStatus cfree_cg_new(CfreeCompiler*, CfreeCg** cg_out);
-CfreeStatus cfree_cg_begin_obj(CfreeCg*, CfreeObjBuilder* out,
+CFREE_API CfreeStatus cfree_cg_new(CfreeCompiler*, CfreeCg** cg_out);
+CFREE_API CfreeStatus cfree_cg_begin_obj(CfreeCg*, CfreeObjBuilder* out,
const CfreeCodeOptions*);
-CfreeStatus cfree_cg_end_obj(CfreeCg*);
-void cfree_cg_free(CfreeCg*);
+CFREE_API CfreeStatus cfree_cg_end_obj(CfreeCg*);
+CFREE_API void cfree_cg_free(CfreeCg*);
/* Sticky source location. Function, scope, local, param, instruction, and
* data-definition debug records use the current location. */
-void cfree_cg_set_loc(CfreeCg*, CfreeSrcLoc);
+CFREE_API void cfree_cg_set_loc(CfreeCg*, CfreeSrcLoc);
/* ============================================================
* Function Bodies and Locals
* ============================================================ */
-void cfree_cg_func_begin(CfreeCg*, CfreeCgSym sym);
-void cfree_cg_func_begin_attrs(CfreeCg*, CfreeCgSym sym,
+CFREE_API void cfree_cg_func_begin(CfreeCg*, CfreeCgSym sym);
+CFREE_API void cfree_cg_func_begin_attrs(CfreeCg*, CfreeCgSym sym,
CfreeCgFuncAttrs attrs);
-void cfree_cg_func_end(CfreeCg*);
+CFREE_API void cfree_cg_func_end(CfreeCg*);
typedef enum CfreeCgLocalFlag {
CFREE_CG_LOCALFLAG_NONE = 0,
@@ -431,17 +431,17 @@ typedef struct CfreeCgLocalAttrs {
uint32_t flags; /* CfreeCgLocalFlag */
} CfreeCgLocalAttrs;
-CfreeCgLocal cfree_cg_local(CfreeCg*, CfreeCgTypeId type,
+CFREE_API CfreeCgLocal cfree_cg_local(CfreeCg*, CfreeCgTypeId type,
CfreeCgLocalAttrs attrs);
/* Declares a source parameter as a local handle. Parameters must be declared
* in order before ordinary locals; therefore the first n parameter handles in
* a function are also the first n local ids. */
-CfreeCgLocal cfree_cg_param(CfreeCg*, uint32_t index, CfreeCgTypeId type,
+CFREE_API CfreeCgLocal cfree_cg_param(CfreeCg*, uint32_t index, CfreeCgTypeId type,
CfreeCgLocalAttrs attrs);
/* Pops a byte size and pushes a pointer to stack storage with at least align
* alignment. The allocation lifetime is the current function activation. */
-void cfree_cg_alloca(CfreeCg*, uint32_t align, CfreeCgTypeId result_ptr_type);
+CFREE_API void cfree_cg_alloca(CfreeCg*, uint32_t align, CfreeCgTypeId result_ptr_type);
/* ============================================================
* Control flow
@@ -462,29 +462,29 @@ void cfree_cg_alloca(CfreeCg*, uint32_t align, CfreeCgTypeId result_ptr_type);
*
* continue/continue_true/continue_false never carry a result; they jump to
* the loop header, not the scope exit. */
-CfreeCgScope cfree_cg_scope_begin(CfreeCg*, CfreeCgTypeId result_type);
-void cfree_cg_scope_end(CfreeCg*, CfreeCgScope);
+CFREE_API CfreeCgScope cfree_cg_scope_begin(CfreeCg*, CfreeCgTypeId result_type);
+CFREE_API void cfree_cg_scope_end(CfreeCg*, CfreeCgScope);
/* Expose the labels CG minted for this scope. Frontends that emit
* unstructured `jump`/`branch` ops (rather than going through the
* scope_break/scope_continue helpers) can use these to land control at
* the scope's break/continue points — handy when the same backend needs
* to translate label-targeted jumps back into structured `break;`/
* `continue;` later (the C source target does this). */
-CfreeCgLabel cfree_cg_scope_break_label(CfreeCg*, CfreeCgScope);
-CfreeCgLabel cfree_cg_scope_continue_label(CfreeCg*, CfreeCgScope);
-void cfree_cg_break(CfreeCg*, CfreeCgScope);
-void cfree_cg_break_true(CfreeCg*, CfreeCgScope);
-void cfree_cg_break_false(CfreeCg*, CfreeCgScope);
-void cfree_cg_continue(CfreeCg*, CfreeCgScope);
-void cfree_cg_continue_true(CfreeCg*, CfreeCgScope);
-void cfree_cg_continue_false(CfreeCg*, CfreeCgScope);
+CFREE_API CfreeCgLabel cfree_cg_scope_break_label(CfreeCg*, CfreeCgScope);
+CFREE_API CfreeCgLabel cfree_cg_scope_continue_label(CfreeCg*, CfreeCgScope);
+CFREE_API void cfree_cg_break(CfreeCg*, CfreeCgScope);
+CFREE_API void cfree_cg_break_true(CfreeCg*, CfreeCgScope);
+CFREE_API void cfree_cg_break_false(CfreeCg*, CfreeCgScope);
+CFREE_API void cfree_cg_continue(CfreeCg*, CfreeCgScope);
+CFREE_API void cfree_cg_continue_true(CfreeCg*, CfreeCgScope);
+CFREE_API void cfree_cg_continue_false(CfreeCg*, CfreeCgScope);
/* Unstructured labels and jumps. */
-CfreeCgLabel cfree_cg_label_new(CfreeCg*);
-void cfree_cg_label_place(CfreeCg*, CfreeCgLabel);
-void cfree_cg_jump(CfreeCg*, CfreeCgLabel);
-void cfree_cg_branch_true(CfreeCg*, CfreeCgLabel);
-void cfree_cg_branch_false(CfreeCg*, CfreeCgLabel);
+CFREE_API CfreeCgLabel cfree_cg_label_new(CfreeCg*);
+CFREE_API void cfree_cg_label_place(CfreeCg*, CfreeCgLabel);
+CFREE_API void cfree_cg_jump(CfreeCg*, CfreeCgLabel);
+CFREE_API void cfree_cg_branch_true(CfreeCg*, CfreeCgLabel);
+CFREE_API void cfree_cg_branch_false(CfreeCg*, CfreeCgLabel);
typedef struct CfreeCgSwitchCase {
uint64_t value; /* bit pattern interpreted using selector_type */
@@ -512,60 +512,60 @@ typedef struct CfreeCgSwitch {
* threading) pass dense case values 0..N-1 — backends can detect the
* shape and emit a real table; the C target lets the host compiler
* decide. The hint is advisory; targets may ignore it. */
-void cfree_cg_switch(CfreeCg*, CfreeCgSwitch sw);
+CFREE_API void cfree_cg_switch(CfreeCg*, CfreeCgSwitch sw);
/* Pushes the address of a label in the current function. Label addresses are
* first-class pointer values for direct-threaded interpreters: they may be
* stored, loaded, selected from tables, compared for equality, and consumed by
* cfree_cg_computed_goto. They are only valid within the defining function's
* dynamic activation and must not be called or dereferenced as data. */
-void cfree_cg_push_label_addr(CfreeCg*, CfreeCgLabel, CfreeCgTypeId ptr_type);
+CFREE_API void cfree_cg_push_label_addr(CfreeCg*, CfreeCgLabel, CfreeCgTypeId ptr_type);
/* Pops a label address and branches to it. valid_targets must name the
* non-empty closed set of labels the target may resolve to; targets use it
* for validation, CFG construction, and branch-protection lowering. */
-void cfree_cg_computed_goto(CfreeCg*, const CfreeCgLabel* valid_targets,
+CFREE_API void cfree_cg_computed_goto(CfreeCg*, const CfreeCgLabel* valid_targets,
uint32_t ntargets);
/* Terminates the current block with unreachable code. This is a real
* terminator, not a side-effect intrinsic. */
-void cfree_cg_unreachable(CfreeCg*);
+CFREE_API void cfree_cg_unreachable(CfreeCg*);
/* ============================================================
* Value Stack and Lvalues
* ============================================================ */
-void cfree_cg_dup(CfreeCg*);
-void cfree_cg_dup2(CfreeCg*); /* duplicates the top two slots */
-void cfree_cg_swap(CfreeCg*);
-void cfree_cg_drop(CfreeCg*);
-void cfree_cg_rot3(CfreeCg*); /* [..., a, b, c] -> [..., b, c, a] */
+CFREE_API void cfree_cg_dup(CfreeCg*);
+CFREE_API void cfree_cg_dup2(CfreeCg*); /* duplicates the top two slots */
+CFREE_API void cfree_cg_swap(CfreeCg*);
+CFREE_API void cfree_cg_drop(CfreeCg*);
+CFREE_API void cfree_cg_rot3(CfreeCg*); /* [..., a, b, c] -> [..., b, c, a] */
/* Returns nonzero when the current top-of-stack value is a compile-time known
* integer-like immediate. The value is not popped. */
-int cfree_cg_top_const_int(CfreeCg*, int64_t* out_value);
+CFREE_API int cfree_cg_top_const_int(CfreeCg*, int64_t* out_value);
-void cfree_cg_push_int(CfreeCg*, uint64_t value, CfreeCgTypeId type);
-void cfree_cg_push_float(CfreeCg*, double value, CfreeCgTypeId type);
-void cfree_cg_push_null(CfreeCg*, CfreeCgTypeId ptr_type);
-void cfree_cg_push_local(CfreeCg*, CfreeCgLocal local);
-void cfree_cg_push_local_addr(CfreeCg*, CfreeCgLocal local);
+CFREE_API void cfree_cg_push_int(CfreeCg*, uint64_t value, CfreeCgTypeId type);
+CFREE_API void cfree_cg_push_float(CfreeCg*, double value, CfreeCgTypeId type);
+CFREE_API void cfree_cg_push_null(CfreeCg*, CfreeCgTypeId ptr_type);
+CFREE_API void cfree_cg_push_local(CfreeCg*, CfreeCgLocal local);
+CFREE_API void cfree_cg_push_local_addr(CfreeCg*, CfreeCgLocal local);
/* Anonymous immutable data. Returns a local readonly object symbol; callers
* can materialize its address with push_symbol_addr. pointee_type describes
* the logical value at that address, enabling const_data + indirect + load to
* materialize arbitrary-width constants. */
-CfreeCgSym cfree_cg_const_data(CfreeCg*, const uint8_t* data, size_t len,
+CFREE_API CfreeCgSym cfree_cg_const_data(CfreeCg*, const uint8_t* data, size_t len,
uint32_t align, CfreeCgTypeId pointee_type);
/* Pushes &sym + addend as a pointer rvalue. For TLS objects this means the
* address of the current thread's instance; the target chooses LE/IE/GD/TLVP
* or equivalent lowering from the symbol attrs and output mode. */
-void cfree_cg_push_symbol_addr(CfreeCg*, CfreeCgSym sym, int64_t addend);
+CFREE_API void cfree_cg_push_symbol_addr(CfreeCg*, CfreeCgSym sym, int64_t addend);
/* Projects an lvalue TOS back to a pointer rvalue (e.g. for `&x`, passing to
* a call, escape). */
-void cfree_cg_addr(CfreeCg*);
+CFREE_API void cfree_cg_addr(CfreeCg*);
/* Single load/store ops with an effective-address rider.
*
@@ -582,8 +582,8 @@ void cfree_cg_addr(CfreeCg*);
* scale > 0:
* load: [base, index] -> [value]
* store: [base, index, value] -> [] */
-void cfree_cg_load(CfreeCg*, CfreeCgMemAccess access, CfreeCgEffAddr ea);
-void cfree_cg_store(CfreeCg*, CfreeCgMemAccess access, CfreeCgEffAddr ea);
+CFREE_API void cfree_cg_load(CfreeCg*, CfreeCgMemAccess access, CfreeCgEffAddr ea);
+CFREE_API void cfree_cg_store(CfreeCg*, CfreeCgMemAccess access, CfreeCgEffAddr ea);
/* ============================================================
* ABI variadic argument access
@@ -595,11 +595,11 @@ void cfree_cg_store(CfreeCg*, CfreeCgMemAccess access, CfreeCgEffAddr ea);
* The frontend allocates a local of CFREE_CG_BUILTIN_VARARG_STATE and pushes
* that local's address before each operation. The implementation reads and
* writes the state in memory according to the target ABI. */
-void cfree_cg_vararg_start(CfreeCg*); /* pop &state */
-void cfree_cg_vararg_next(CfreeCg*,
+CFREE_API void cfree_cg_vararg_start(CfreeCg*); /* pop &state */
+CFREE_API void cfree_cg_vararg_next(CfreeCg*,
CfreeCgTypeId type); /* pop &state; push value */
-void cfree_cg_vararg_end(CfreeCg*); /* pop &state */
-void cfree_cg_vararg_copy(CfreeCg*); /* pop &dst, &src */
+CFREE_API void cfree_cg_vararg_end(CfreeCg*); /* pop &state */
+CFREE_API void cfree_cg_vararg_copy(CfreeCg*); /* pop &dst, &src */
/* ============================================================
* Integer Operations
@@ -653,9 +653,9 @@ typedef enum CfreeCgIntUnOp {
CFREE_CG_INT_BNOT,
} CfreeCgIntUnOp;
-void cfree_cg_int_binop(CfreeCg*, CfreeCgIntBinOp, uint32_t flags);
-void cfree_cg_int_unop(CfreeCg*, CfreeCgIntUnOp, uint32_t flags);
-void cfree_cg_int_cmp(CfreeCg*, CfreeCgIntCmpOp);
+CFREE_API void cfree_cg_int_binop(CfreeCg*, CfreeCgIntBinOp, uint32_t flags);
+CFREE_API void cfree_cg_int_unop(CfreeCg*, CfreeCgIntUnOp, uint32_t flags);
+CFREE_API void cfree_cg_int_cmp(CfreeCg*, CfreeCgIntCmpOp);
/* ============================================================
* Floating-Point Operations
@@ -698,9 +698,9 @@ typedef enum CfreeCgFpFlag {
CFREE_CG_FP_APPROX = 1u << 5,
} CfreeCgFpFlag;
-void cfree_cg_fp_binop(CfreeCg*, CfreeCgFpBinOp, uint32_t flags);
-void cfree_cg_fp_unop(CfreeCg*, CfreeCgFpUnOp, uint32_t flags);
-void cfree_cg_fp_cmp(CfreeCg*, CfreeCgFpCmpOp);
+CFREE_API void cfree_cg_fp_binop(CfreeCg*, CfreeCgFpBinOp, uint32_t flags);
+CFREE_API void cfree_cg_fp_unop(CfreeCg*, CfreeCgFpUnOp, uint32_t flags);
+CFREE_API void cfree_cg_fp_cmp(CfreeCg*, CfreeCgFpCmpOp);
/* ============================================================
* Conversions
@@ -714,21 +714,21 @@ typedef enum CfreeCgRounding {
CFREE_CG_ROUND_UP,
} CfreeCgRounding;
-void cfree_cg_sext(CfreeCg*, CfreeCgTypeId dst);
-void cfree_cg_zext(CfreeCg*, CfreeCgTypeId dst);
-void cfree_cg_trunc(CfreeCg*, CfreeCgTypeId dst);
-void cfree_cg_ptr_to_int(CfreeCg*, CfreeCgTypeId dst);
-void cfree_cg_int_to_ptr(CfreeCg*, CfreeCgTypeId dst);
-void cfree_cg_bitcast(CfreeCg*, CfreeCgTypeId dst);
-void cfree_cg_fpext(CfreeCg*, CfreeCgTypeId dst);
-void cfree_cg_fptrunc(CfreeCg*, CfreeCgTypeId dst);
-void cfree_cg_sint_to_float(CfreeCg*, CfreeCgTypeId dst,
+CFREE_API void cfree_cg_sext(CfreeCg*, CfreeCgTypeId dst);
+CFREE_API void cfree_cg_zext(CfreeCg*, CfreeCgTypeId dst);
+CFREE_API void cfree_cg_trunc(CfreeCg*, CfreeCgTypeId dst);
+CFREE_API void cfree_cg_ptr_to_int(CfreeCg*, CfreeCgTypeId dst);
+CFREE_API void cfree_cg_int_to_ptr(CfreeCg*, CfreeCgTypeId dst);
+CFREE_API void cfree_cg_bitcast(CfreeCg*, CfreeCgTypeId dst);
+CFREE_API void cfree_cg_fpext(CfreeCg*, CfreeCgTypeId dst);
+CFREE_API void cfree_cg_fptrunc(CfreeCg*, CfreeCgTypeId dst);
+CFREE_API void cfree_cg_sint_to_float(CfreeCg*, CfreeCgTypeId dst,
CfreeCgRounding rounding);
-void cfree_cg_uint_to_float(CfreeCg*, CfreeCgTypeId dst,
+CFREE_API void cfree_cg_uint_to_float(CfreeCg*, CfreeCgTypeId dst,
CfreeCgRounding rounding);
-void cfree_cg_float_to_sint(CfreeCg*, CfreeCgTypeId dst,
+CFREE_API void cfree_cg_float_to_sint(CfreeCg*, CfreeCgTypeId dst,
CfreeCgRounding rounding);
-void cfree_cg_float_to_uint(CfreeCg*, CfreeCgTypeId dst,
+CFREE_API void cfree_cg_float_to_uint(CfreeCg*, CfreeCgTypeId dst,
CfreeCgRounding rounding);
/* ============================================================
@@ -758,12 +758,12 @@ typedef struct CfreeCgCallAttrs {
* allowing the backend/linker to choose PLT/stub/IAT/direct/IFUNC handling.
* MUST tail calls should fail diagnostically if the ABI shapes are not
* compatible. */
-void cfree_cg_call(CfreeCg*, uint32_t nargs, CfreeCgTypeId fn_type,
+CFREE_API void cfree_cg_call(CfreeCg*, uint32_t nargs, CfreeCgTypeId fn_type,
CfreeCgCallAttrs attrs);
-void cfree_cg_call_symbol(CfreeCg*, CfreeCgSym sym, uint32_t nargs,
+CFREE_API void cfree_cg_call_symbol(CfreeCg*, CfreeCgSym sym, uint32_t nargs,
CfreeCgCallAttrs attrs);
-void cfree_cg_ret(CfreeCg*);
-void cfree_cg_ret_void(CfreeCg*);
+CFREE_API void cfree_cg_ret(CfreeCg*);
+CFREE_API void cfree_cg_ret_void(CfreeCg*);
/* ============================================================
* Intrinsics
@@ -822,7 +822,7 @@ typedef enum CfreeCgBarrierScope {
* 1: the syscall number plus 0..6 long arguments. Runtime-extension intrinsics
* mirror rt/include/cfree/{syscall,baremetal,coro}.h and must diagnose targets
* where the primitive has no legal lowering. */
-void cfree_cg_intrinsic(CfreeCg*, CfreeCgIntrinsic, uint32_t nargs,
+CFREE_API void cfree_cg_intrinsic(CfreeCg*, CfreeCgIntrinsic, uint32_t nargs,
CfreeCgTypeId result_type);
/* ============================================================
@@ -832,11 +832,11 @@ void cfree_cg_intrinsic(CfreeCg*, CfreeCgIntrinsic, uint32_t nargs,
/* Stack:
* memcpy/memmove: [dst, src] -> []
* memset: [dst] -> [] */
-void cfree_cg_memcpy(CfreeCg*, uint64_t size, CfreeCgMemAccess dst,
+CFREE_API void cfree_cg_memcpy(CfreeCg*, uint64_t size, CfreeCgMemAccess dst,
CfreeCgMemAccess src);
-void cfree_cg_memmove(CfreeCg*, uint64_t size, CfreeCgMemAccess dst,
+CFREE_API void cfree_cg_memmove(CfreeCg*, uint64_t size, CfreeCgMemAccess dst,
CfreeCgMemAccess src);
-void cfree_cg_memset(CfreeCg*, uint8_t val, uint64_t size,
+CFREE_API void cfree_cg_memset(CfreeCg*, uint8_t val, uint64_t size,
CfreeCgMemAccess dst);
/* ============================================================
@@ -862,20 +862,20 @@ typedef enum CfreeCgMemOrder {
CFREE_CG_MO_SEQ_CST,
} CfreeCgMemOrder;
-int cfree_cg_atomic_is_legal(CfreeCompiler*, CfreeCgMemAccess access,
+CFREE_API int cfree_cg_atomic_is_legal(CfreeCompiler*, CfreeCgMemAccess access,
CfreeCgMemOrder order);
-int cfree_cg_atomic_is_lock_free(CfreeCompiler*, CfreeCgMemAccess access);
-void cfree_cg_atomic_load(CfreeCg*, CfreeCgMemAccess access,
+CFREE_API int cfree_cg_atomic_is_lock_free(CfreeCompiler*, CfreeCgMemAccess access);
+CFREE_API void cfree_cg_atomic_load(CfreeCg*, CfreeCgMemAccess access,
CfreeCgMemOrder order);
-void cfree_cg_atomic_store(CfreeCg*, CfreeCgMemAccess access,
+CFREE_API void cfree_cg_atomic_store(CfreeCg*, CfreeCgMemAccess access,
CfreeCgMemOrder order);
-void cfree_cg_atomic_rmw(CfreeCg*, CfreeCgMemAccess access, CfreeCgAtomicOp,
+CFREE_API void cfree_cg_atomic_rmw(CfreeCg*, CfreeCgMemAccess access, CfreeCgAtomicOp,
CfreeCgMemOrder order);
/* Stack: [ptr, expected, desired] -> [prior, ok_bool]. */
-void cfree_cg_atomic_cmpxchg(CfreeCg*, CfreeCgMemAccess access,
+CFREE_API void cfree_cg_atomic_cmpxchg(CfreeCg*, CfreeCgMemAccess access,
CfreeCgMemOrder success, CfreeCgMemOrder failure,
int weak);
-void cfree_cg_atomic_fence(CfreeCg*, CfreeCgMemOrder);
+CFREE_API void cfree_cg_atomic_fence(CfreeCg*, CfreeCgMemOrder);
/* ============================================================
* Inline Assembly
@@ -931,8 +931,8 @@ typedef struct CfreeCgInlineAsm {
* in the per-operand constraint string. Template, constraints, and clobbers
* are pre-interned strings. clobber_abi_sets names target-defined ABI register
* sets such as all caller-saved registers. */
-void cfree_cg_inline_asm(CfreeCg*, CfreeCgInlineAsm asm_block);
-void cfree_cg_file_scope_asm(CfreeCg*, CfreeSlice asm_source);
+CFREE_API void cfree_cg_inline_asm(CfreeCg*, CfreeCgInlineAsm asm_block);
+CFREE_API void cfree_cg_file_scope_asm(CfreeCg*, CfreeSlice asm_source);
/* ============================================================
* Data Definitions
@@ -965,25 +965,25 @@ typedef struct CfreeCgDataDefAttrs {
* function remains open across data_begin/data_end so frontends can define
* block-scope statics and computed-goto dispatch tables that need function
* label context. */
-void cfree_cg_data_begin(CfreeCg*, CfreeCgSym sym, CfreeCgDataDefAttrs attrs);
-void cfree_cg_data_common(CfreeCg*, CfreeCgSym sym, uint64_t size,
+CFREE_API void cfree_cg_data_begin(CfreeCg*, CfreeCgSym sym, CfreeCgDataDefAttrs attrs);
+CFREE_API void cfree_cg_data_common(CfreeCg*, CfreeCgSym sym, uint64_t size,
uint32_t align);
-void cfree_cg_data_end(CfreeCg*);
+CFREE_API void cfree_cg_data_end(CfreeCg*);
/* Appends to the currently open data definition. */
-void cfree_cg_data_align(CfreeCg*, uint32_t align);
-void cfree_cg_data_pad(CfreeCg*, uint64_t size, uint8_t value);
-void cfree_cg_data_int(CfreeCg*, uint64_t value, CfreeCgTypeId type);
-void cfree_cg_data_float(CfreeCg*, double value, CfreeCgTypeId type);
-void cfree_cg_data_bytes(CfreeCg*, const uint8_t* data, size_t len);
-void cfree_cg_data_zero(CfreeCg*, uint64_t size);
+CFREE_API void cfree_cg_data_align(CfreeCg*, uint32_t align);
+CFREE_API void cfree_cg_data_pad(CfreeCg*, uint64_t size, uint8_t value);
+CFREE_API void cfree_cg_data_int(CfreeCg*, uint64_t value, CfreeCgTypeId type);
+CFREE_API void cfree_cg_data_float(CfreeCg*, double value, CfreeCgTypeId type);
+CFREE_API void cfree_cg_data_bytes(CfreeCg*, const uint8_t* data, size_t len);
+CFREE_API void cfree_cg_data_zero(CfreeCg*, uint64_t size);
/* Relocatable data expressions. These describe the value encoded in the data
* stream; they do not request a lowering strategy such as GOT, PLT, TLVP, or
* a TLS access model. width is the encoded field width in bytes. address_space
* is the pointer address space of address constants; use 0 for the target data
* address space. */
-void cfree_cg_data_addr(CfreeCg*, CfreeCgSym target, int64_t addend,
+CFREE_API void cfree_cg_data_addr(CfreeCg*, CfreeCgSym target, int64_t addend,
uint32_t width, uint32_t address_space);
/* Encodes a function-local label address for direct-threaded dispatch tables.
* The target label must have been created by cfree_cg_label_new; it does not
@@ -996,11 +996,11 @@ void cfree_cg_data_addr(CfreeCg*, CfreeCgSym target, int64_t addend,
* selected from tables, and consumed by cfree_cg_computed_goto in the label's
* defining function. It must not be called, dereferenced as data, or used by
* another function's computed goto. */
-void cfree_cg_data_label_addr(CfreeCg*, CfreeCgLabel target, int64_t addend,
+CFREE_API void cfree_cg_data_label_addr(CfreeCg*, CfreeCgLabel target, int64_t addend,
uint32_t width, uint32_t address_space);
-void cfree_cg_data_pcrel(CfreeCg*, CfreeCgSym target, int64_t addend,
+CFREE_API void cfree_cg_data_pcrel(CfreeCg*, CfreeCgSym target, int64_t addend,
uint32_t width);
-void cfree_cg_data_symdiff(CfreeCg*, CfreeCgSym lhs, CfreeCgSym rhs,
+CFREE_API void cfree_cg_data_symdiff(CfreeCg*, CfreeCgSym lhs, CfreeCgSym rhs,
int64_t addend, uint32_t width);
/* ============================================================
diff --git a/include/cfree/compile.h b/include/cfree/compile.h
@@ -85,11 +85,11 @@ typedef struct CfreeFrontendVTable {
uint32_t nextensions;
} CfreeFrontendVTable;
-CfreeLanguage cfree_language_for_path(CfreeCompiler*, const char* path);
-CfreeStatus cfree_register_frontend(CfreeCompiler*, CfreeLanguage,
+CFREE_API CfreeLanguage cfree_language_for_path(CfreeCompiler*, const char* path);
+CFREE_API CfreeStatus cfree_register_frontend(CfreeCompiler*, CfreeLanguage,
const CfreeFrontendVTable*);
-uint32_t cfree_compiler_arch_predefines(CfreeCompiler*,
+CFREE_API uint32_t cfree_compiler_arch_predefines(CfreeCompiler*,
const CfreePredefinedMacro** out);
typedef struct CfreeCompileSessionOptions {
@@ -97,13 +97,13 @@ typedef struct CfreeCompileSessionOptions {
CfreeFrontendCompileOptions compile;
} CfreeCompileSessionOptions;
-CfreeStatus cfree_compile_session_new(CfreeCompiler*,
+CFREE_API CfreeStatus cfree_compile_session_new(CfreeCompiler*,
const CfreeCompileSessionOptions*,
CfreeCompileSession** out);
-CfreeStatus cfree_compile_session_compile(CfreeCompileSession*,
+CFREE_API CfreeStatus cfree_compile_session_compile(CfreeCompileSession*,
const CfreeSourceInput*,
CfreeObjBuilder** out);
-void cfree_compile_session_free(CfreeCompileSession*);
+CFREE_API void cfree_compile_session_free(CfreeCompileSession*);
typedef struct CfreeDepIter CfreeDepIter;
@@ -116,8 +116,8 @@ typedef struct CfreeDepEdge {
uint8_t pad[2];
} CfreeDepEdge;
-CfreeStatus cfree_dep_iter_new(CfreeCompiler*, CfreeDepIter** out);
-CfreeIterResult cfree_dep_iter_next(CfreeDepIter*, CfreeDepEdge* out);
-void cfree_dep_iter_free(CfreeDepIter*);
+CFREE_API CfreeStatus cfree_dep_iter_new(CfreeCompiler*, CfreeDepIter** out);
+CFREE_API CfreeIterResult cfree_dep_iter_next(CfreeDepIter*, CfreeDepEdge* out);
+CFREE_API void cfree_dep_iter_free(CfreeDepIter*);
#endif
diff --git a/include/cfree/core.h b/include/cfree/core.h
@@ -304,22 +304,22 @@ typedef struct CfreeContext {
int64_t now;
} CfreeContext;
-CfreeStatus cfree_compiler_new(CfreeTarget, const CfreeContext*,
+CFREE_API CfreeStatus cfree_compiler_new(CfreeTarget, const CfreeContext*,
CfreeCompiler** out);
-void cfree_compiler_free(CfreeCompiler*);
-CfreeTarget cfree_compiler_target(CfreeCompiler*);
+CFREE_API void cfree_compiler_free(CfreeCompiler*);
+CFREE_API CfreeTarget cfree_compiler_target(CfreeCompiler*);
-const CfreeContext* cfree_compiler_context(CfreeCompiler*);
+CFREE_API const CfreeContext* cfree_compiler_context(CfreeCompiler*);
-CfreeSlice cfree_compiler_file_name(CfreeCompiler*, uint32_t file_id);
+CFREE_API CfreeSlice cfree_compiler_file_name(CfreeCompiler*, uint32_t file_id);
/* Intern a slice's bytes, returning its canonical symbol (0 for the empty
* slice). Retrieve the bytes with cfree_sym_str, which returns a slice whose
* pointer is NUL-terminated (the NUL is not counted in len). */
-CfreeSym cfree_sym_intern(CfreeCompiler*, CfreeSlice);
-CfreeSlice cfree_sym_str(CfreeCompiler*, CfreeSym);
+CFREE_API CfreeSym cfree_sym_intern(CfreeCompiler*, CfreeSlice);
+CFREE_API CfreeSlice cfree_sym_str(CfreeCompiler*, CfreeSym);
-CfreeStatus cfree_writer_mem(CfreeHeap*, CfreeWriter** out);
-const uint8_t* cfree_writer_mem_bytes(CfreeWriter*, size_t* len_out);
+CFREE_API CfreeStatus cfree_writer_mem(CfreeHeap*, CfreeWriter** out);
+CFREE_API const uint8_t* cfree_writer_mem_bytes(CfreeWriter*, size_t* len_out);
#endif
diff --git a/include/cfree/dbg.h b/include/cfree/dbg.h
@@ -88,37 +88,37 @@ typedef struct CfreeBreakpointSpec {
void *condition_user;
} CfreeBreakpointSpec;
-CfreeStatus cfree_jit_session_new(CfreeJit *, const CfreeDbgHost *,
+CFREE_API CfreeStatus cfree_jit_session_new(CfreeJit *, const CfreeDbgHost *,
CfreeJitSession **out);
-void cfree_jit_session_free(CfreeJitSession *);
-CfreeStatus cfree_jit_session_attach_dwarf(CfreeJitSession *,
+CFREE_API void cfree_jit_session_free(CfreeJitSession *);
+CFREE_API CfreeStatus cfree_jit_session_attach_dwarf(CfreeJitSession *,
CfreeDebugInfo *);
-CfreeStatus cfree_jit_session_call(CfreeJitSession *, void *entry,
+CFREE_API CfreeStatus cfree_jit_session_call(CfreeJitSession *, void *entry,
CfreeEntryKind, int argc, char **argv,
CfreeStopInfo *stop_out);
-CfreeStatus cfree_jit_session_call_u64(CfreeJitSession *, void *entry,
+CFREE_API CfreeStatus cfree_jit_session_call_u64(CfreeJitSession *, void *entry,
const uint64_t *args, uint32_t nargs,
uint64_t *ret_out,
CfreeStopInfo *stop_out);
-CfreeStatus cfree_jit_session_resume(CfreeJitSession *, CfreeResumeMode,
+CFREE_API CfreeStatus cfree_jit_session_resume(CfreeJitSession *, CfreeResumeMode,
CfreeStopInfo *stop_out);
-CfreeStatus cfree_jit_session_interrupt(CfreeJitSession *);
+CFREE_API CfreeStatus cfree_jit_session_interrupt(CfreeJitSession *);
-CfreeStatus cfree_jit_session_read_mem(CfreeJitSession *, uint64_t addr,
+CFREE_API CfreeStatus cfree_jit_session_read_mem(CfreeJitSession *, uint64_t addr,
void *dst, size_t n);
-CfreeStatus cfree_jit_session_write_mem(CfreeJitSession *, uint64_t addr,
+CFREE_API CfreeStatus cfree_jit_session_write_mem(CfreeJitSession *, uint64_t addr,
const void *src, size_t n);
-CfreeStatus cfree_jit_session_get_regs(CfreeJitSession *,
+CFREE_API CfreeStatus cfree_jit_session_get_regs(CfreeJitSession *,
CfreeUnwindFrame *out);
-CfreeStatus cfree_jit_session_set_regs(CfreeJitSession *,
+CFREE_API CfreeStatus cfree_jit_session_set_regs(CfreeJitSession *,
const CfreeUnwindFrame *);
-CfreeStatus cfree_jit_session_breakpoint_set(CfreeJitSession *, uint64_t addr,
+CFREE_API CfreeStatus cfree_jit_session_breakpoint_set(CfreeJitSession *, uint64_t addr,
uint32_t *bp_id_out);
-CfreeStatus cfree_jit_session_breakpoint_clear(CfreeJitSession *,
+CFREE_API CfreeStatus cfree_jit_session_breakpoint_clear(CfreeJitSession *,
uint32_t bp_id);
-CfreeStatus cfree_jit_session_breakpoint_set_spec(CfreeJitSession *,
+CFREE_API CfreeStatus cfree_jit_session_breakpoint_set_spec(CfreeJitSession *,
const CfreeBreakpointSpec *,
uint32_t *bp_id_out);
diff --git a/include/cfree/disasm.h b/include/cfree/disasm.h
@@ -26,17 +26,17 @@ typedef struct CfreeDisasmContext {
CfreeContext context;
} CfreeDisasmContext;
-CfreeStatus cfree_disasm_iter_new(const CfreeDisasmContext *,
+CFREE_API CfreeStatus cfree_disasm_iter_new(const CfreeDisasmContext *,
const uint8_t *bytes, size_t len,
uint64_t vaddr,
const CfreeObjFile *annotations,
CfreeDisasmIter **out);
-CfreeIterResult cfree_disasm_iter_next(CfreeDisasmIter *, CfreeInsn *out);
-void cfree_disasm_iter_free(CfreeDisasmIter *);
+CFREE_API CfreeIterResult cfree_disasm_iter_next(CfreeDisasmIter *, CfreeInsn *out);
+CFREE_API void cfree_disasm_iter_free(CfreeDisasmIter *);
-CfreeStatus cfree_disasm_obj(const CfreeContext *, const CfreeObjFile *,
+CFREE_API CfreeStatus cfree_disasm_obj(const CfreeContext *, const CfreeObjFile *,
CfreeWriter *out);
-CfreeStatus cfree_disasm_obj_bytes(const CfreeContext *, const CfreeSlice *,
+CFREE_API CfreeStatus cfree_disasm_obj_bytes(const CfreeContext *, const CfreeSlice *,
CfreeWriter *out);
#endif
diff --git a/include/cfree/dwarf.h b/include/cfree/dwarf.h
@@ -14,14 +14,14 @@
typedef struct CfreeDwarfType CfreeDwarfType;
-CfreeStatus cfree_dwarf_open(const CfreeContext *, const CfreeObjFile *,
+CFREE_API CfreeStatus cfree_dwarf_open(const CfreeContext *, const CfreeObjFile *,
CfreeDebugInfo **out);
-void cfree_dwarf_free(CfreeDebugInfo *);
+CFREE_API void cfree_dwarf_free(CfreeDebugInfo *);
-CfreeStatus cfree_dwarf_addr_to_line(CfreeDebugInfo *, uint64_t pc,
+CFREE_API CfreeStatus cfree_dwarf_addr_to_line(CfreeDebugInfo *, uint64_t pc,
CfreeSlice *file_out,
uint32_t *line_out, uint32_t *col_out);
-CfreeStatus cfree_dwarf_line_to_addr(CfreeDebugInfo *, CfreeSlice file,
+CFREE_API CfreeStatus cfree_dwarf_line_to_addr(CfreeDebugInfo *, CfreeSlice file,
uint32_t line, uint64_t *pc_out);
typedef struct CfreeDwarfLineMatch {
@@ -29,11 +29,11 @@ typedef struct CfreeDwarfLineMatch {
CfreeSlice file;
} CfreeDwarfLineMatch;
-CfreeStatus cfree_dwarf_line_to_addr_all(CfreeDebugInfo *, CfreeSlice file,
+CFREE_API CfreeStatus cfree_dwarf_line_to_addr_all(CfreeDebugInfo *, CfreeSlice file,
uint32_t line,
CfreeDwarfLineMatch *out,
uint32_t cap, uint32_t *n_out);
-CfreeStatus cfree_dwarf_func_at(CfreeDebugInfo *, uint64_t pc,
+CFREE_API CfreeStatus cfree_dwarf_func_at(CfreeDebugInfo *, uint64_t pc,
CfreeSlice *name_out, uint64_t *low_pc_out,
uint64_t *high_pc_out);
@@ -47,11 +47,11 @@ typedef struct CfreeDwarfSubprogram {
bool inlined;
} CfreeDwarfSubprogram;
-CfreeStatus cfree_dwarf_subprogram_at(CfreeDebugInfo *, uint64_t pc,
+CFREE_API CfreeStatus cfree_dwarf_subprogram_at(CfreeDebugInfo *, uint64_t pc,
CfreeDwarfSubprogram *out);
-CfreeStatus cfree_dwarf_subprogram_named(CfreeDebugInfo *, CfreeSlice name,
+CFREE_API CfreeStatus cfree_dwarf_subprogram_named(CfreeDebugInfo *, CfreeSlice name,
CfreeDwarfSubprogram *out);
-CfreeStatus cfree_dwarf_unwind_step(CfreeDebugInfo *, CfreeUnwindFrame *);
+CFREE_API CfreeStatus cfree_dwarf_unwind_step(CfreeDebugInfo *, CfreeUnwindFrame *);
typedef enum CfreeDwarfTypeKind {
CFREE_DT_VOID,
@@ -77,7 +77,7 @@ typedef struct CfreeDwarfTypeInfo {
const CfreeDwarfType *inner;
} CfreeDwarfTypeInfo;
-CfreeDwarfTypeInfo cfree_dwarf_type_info(const CfreeDwarfType *);
+CFREE_API CfreeDwarfTypeInfo cfree_dwarf_type_info(const CfreeDwarfType *);
typedef struct CfreeDwarfFieldIter CfreeDwarfFieldIter;
typedef struct CfreeDwarfField {
@@ -88,12 +88,12 @@ typedef struct CfreeDwarfField {
const CfreeDwarfType *type;
} CfreeDwarfField;
-CfreeStatus cfree_dwarf_field_iter_new(CfreeDebugInfo *,
+CFREE_API CfreeStatus cfree_dwarf_field_iter_new(CfreeDebugInfo *,
const CfreeDwarfType *,
CfreeDwarfFieldIter **out);
-CfreeIterResult cfree_dwarf_field_iter_next(CfreeDwarfFieldIter *,
+CFREE_API CfreeIterResult cfree_dwarf_field_iter_next(CfreeDwarfFieldIter *,
CfreeDwarfField *out);
-void cfree_dwarf_field_iter_free(CfreeDwarfFieldIter *);
+CFREE_API void cfree_dwarf_field_iter_free(CfreeDwarfFieldIter *);
typedef struct CfreeDwarfEnumIter CfreeDwarfEnumIter;
typedef struct CfreeDwarfEnumVal {
@@ -101,12 +101,12 @@ typedef struct CfreeDwarfEnumVal {
int64_t value;
} CfreeDwarfEnumVal;
-CfreeStatus cfree_dwarf_enum_iter_new(CfreeDebugInfo *,
+CFREE_API CfreeStatus cfree_dwarf_enum_iter_new(CfreeDebugInfo *,
const CfreeDwarfType *,
CfreeDwarfEnumIter **out);
-CfreeIterResult cfree_dwarf_enum_iter_next(CfreeDwarfEnumIter *,
+CFREE_API CfreeIterResult cfree_dwarf_enum_iter_next(CfreeDwarfEnumIter *,
CfreeDwarfEnumVal *out);
-void cfree_dwarf_enum_iter_free(CfreeDwarfEnumIter *);
+CFREE_API void cfree_dwarf_enum_iter_free(CfreeDwarfEnumIter *);
typedef enum CfreeDwarfLocKind {
CFREE_DLOC_REG,
@@ -133,9 +133,9 @@ typedef struct CfreeDwarfVarLoc {
typedef CfreeStatus (*CfreeDwarfReadMemFn)(void *user, uint64_t addr,
void *dst, size_t n);
-CfreeStatus cfree_dwarf_var_at(CfreeDebugInfo *, uint64_t pc,
+CFREE_API CfreeStatus cfree_dwarf_var_at(CfreeDebugInfo *, uint64_t pc,
CfreeSlice name, CfreeDwarfVarLoc *out);
-CfreeStatus cfree_dwarf_loc_read(CfreeDebugInfo *, const CfreeDwarfVarLoc *,
+CFREE_API CfreeStatus cfree_dwarf_loc_read(CfreeDebugInfo *, const CfreeDwarfVarLoc *,
const CfreeUnwindFrame *,
CfreeDwarfReadMemFn read_mem, void *read_user,
void *dst, size_t cap, size_t *read_out);
@@ -161,22 +161,22 @@ typedef struct CfreeDwarfVar {
typedef struct CfreeDwarfVarIter CfreeDwarfVarIter;
-CfreeStatus cfree_dwarf_vars_at_new(CfreeDebugInfo *, uint64_t pc,
+CFREE_API CfreeStatus cfree_dwarf_vars_at_new(CfreeDebugInfo *, uint64_t pc,
uint32_t role_mask,
CfreeDwarfVarIter **out);
-CfreeIterResult cfree_dwarf_vars_at_next(CfreeDwarfVarIter *,
+CFREE_API CfreeIterResult cfree_dwarf_vars_at_next(CfreeDwarfVarIter *,
CfreeDwarfVar *out);
-void cfree_dwarf_vars_at_free(CfreeDwarfVarIter *);
+CFREE_API void cfree_dwarf_vars_at_free(CfreeDwarfVarIter *);
typedef struct CfreeDwarfParamIter CfreeDwarfParamIter;
-CfreeStatus cfree_dwarf_param_iter_new(CfreeDebugInfo *, uint64_t pc,
+CFREE_API CfreeStatus cfree_dwarf_param_iter_new(CfreeDebugInfo *, uint64_t pc,
CfreeDwarfParamIter **out);
-CfreeStatus cfree_dwarf_param_iter_new_named(CfreeDebugInfo *,
+CFREE_API CfreeStatus cfree_dwarf_param_iter_new_named(CfreeDebugInfo *,
CfreeSlice name,
CfreeDwarfParamIter **out);
-CfreeIterResult cfree_dwarf_param_iter_next(CfreeDwarfParamIter *,
+CFREE_API CfreeIterResult cfree_dwarf_param_iter_next(CfreeDwarfParamIter *,
CfreeDwarfVar *out);
-void cfree_dwarf_param_iter_free(CfreeDwarfParamIter *);
+CFREE_API void cfree_dwarf_param_iter_free(CfreeDwarfParamIter *);
#endif
diff --git a/include/cfree/emu.h b/include/cfree/emu.h
@@ -101,12 +101,12 @@ typedef struct CfreeEmuOptions {
const char *const *envp;
} CfreeEmuOptions;
-CfreeStatus cfree_emu_run(CfreeCompiler *, const CfreeEmuOptions *,
+CFREE_API CfreeStatus cfree_emu_run(CfreeCompiler *, const CfreeEmuOptions *,
int *out_exit_code);
-CfreeStatus cfree_emu_new(CfreeCompiler *, const CfreeEmuOptions *,
+CFREE_API CfreeStatus cfree_emu_new(CfreeCompiler *, const CfreeEmuOptions *,
CfreeEmu **out);
-CfreeStatus cfree_emu_step(CfreeEmu *, uint32_t nblocks);
-void *cfree_emu_lookup(CfreeEmu *, uint64_t guest_pc);
-void cfree_emu_free(CfreeEmu *);
+CFREE_API CfreeStatus cfree_emu_step(CfreeEmu *, uint32_t nblocks);
+CFREE_API void *cfree_emu_lookup(CfreeEmu *, uint64_t guest_pc);
+CFREE_API void cfree_emu_free(CfreeEmu *);
#endif
diff --git a/include/cfree/frontend.h b/include/cfree/frontend.h
@@ -25,19 +25,19 @@
* internal panic machinery.
*/
typedef CfreeStatus (*CfreeFrontendRunFn)(CfreeCompiler *, void *user);
-CfreeStatus cfree_frontend_run(CfreeCompiler *, CfreeFrontendRunFn, void *user);
+CFREE_API CfreeStatus cfree_frontend_run(CfreeCompiler *, CfreeFrontendRunFn, void *user);
/* Optional metrics bridge for frontends. These are no-ops unless the host
* supplied CfreeContext.metrics. Frontends use this public shim instead of
* depending on libcfree's internal core headers. */
-void cfree_frontend_metrics_scope_begin(CfreeCompiler *, const char *name);
-void cfree_frontend_metrics_scope_end(CfreeCompiler *, const char *name);
-void cfree_frontend_metrics_count(CfreeCompiler *, const char *name,
+CFREE_API void cfree_frontend_metrics_scope_begin(CfreeCompiler *, const char *name);
+CFREE_API void cfree_frontend_metrics_scope_end(CfreeCompiler *, const char *name);
+CFREE_API void cfree_frontend_metrics_count(CfreeCompiler *, const char *name,
uint64_t value);
-_Noreturn void cfree_frontend_fatal(CfreeCompiler *, CfreeSrcLoc,
+CFREE_API _Noreturn void cfree_frontend_fatal(CfreeCompiler *, CfreeSrcLoc,
const char *fmt, ...);
-_Noreturn void cfree_frontend_vfatal(CfreeCompiler *, CfreeSrcLoc,
+CFREE_API _Noreturn void cfree_frontend_vfatal(CfreeCompiler *, CfreeSrcLoc,
const char *fmt, va_list);
#endif
diff --git a/include/cfree/jit.h b/include/cfree/jit.h
@@ -47,10 +47,10 @@ typedef struct CfreeJitHost {
const CfreeJitTls* tls;
} CfreeJitHost;
-void cfree_jit_free(CfreeJit*);
-void* cfree_jit_lookup(CfreeJit*, CfreeSlice name);
-uint64_t cfree_jit_generation(CfreeJit*);
-void cfree_jit_run_dtors(CfreeJit*);
+CFREE_API void cfree_jit_free(CfreeJit*);
+CFREE_API void* cfree_jit_lookup(CfreeJit*, CfreeSlice name);
+CFREE_API uint64_t cfree_jit_generation(CfreeJit*);
+CFREE_API void cfree_jit_run_dtors(CfreeJit*);
typedef enum CfreeJitPublishKind {
CFREE_JIT_PUBLISH_APPEND_OBJECTS,
@@ -66,14 +66,14 @@ typedef struct CfreeJitPublishResult {
uint64_t generation;
} CfreeJitPublishResult;
-CfreeStatus cfree_jit_publish(CfreeJit*, const CfreeJitPublishOptions*,
+CFREE_API CfreeStatus cfree_jit_publish(CfreeJit*, const CfreeJitPublishOptions*,
CfreeJitPublishResult*);
-const CfreeObjFile* cfree_jit_view(CfreeJit*);
-CfreeStatus cfree_jit_addr_to_sym(CfreeJit*, uint64_t addr,
+CFREE_API const CfreeObjFile* cfree_jit_view(CfreeJit*);
+CFREE_API CfreeStatus cfree_jit_addr_to_sym(CfreeJit*, uint64_t addr,
CfreeSlice* name_out, uint64_t* off_out);
-uint64_t cfree_jit_runtime_to_image(CfreeJit*, uint64_t runtime_pc);
-uint64_t cfree_jit_image_to_runtime(CfreeJit*, uint64_t image_vaddr);
+CFREE_API uint64_t cfree_jit_runtime_to_image(CfreeJit*, uint64_t runtime_pc);
+CFREE_API uint64_t cfree_jit_image_to_runtime(CfreeJit*, uint64_t image_vaddr);
typedef struct CfreeJitSymIter CfreeJitSymIter;
@@ -84,8 +84,8 @@ typedef struct CfreeJitSym {
CfreeSymKind kind;
} CfreeJitSym;
-CfreeStatus cfree_jit_sym_iter_new(CfreeJit*, CfreeJitSymIter** out);
-CfreeIterResult cfree_jit_sym_iter_next(CfreeJitSymIter*, CfreeJitSym* out);
-void cfree_jit_sym_iter_free(CfreeJitSymIter*);
+CFREE_API CfreeStatus cfree_jit_sym_iter_new(CfreeJit*, CfreeJitSymIter** out);
+CFREE_API CfreeIterResult cfree_jit_sym_iter_next(CfreeJitSymIter*, CfreeJitSym* out);
+CFREE_API void cfree_jit_sym_iter_free(CfreeJitSymIter*);
#endif
diff --git a/include/cfree/link.h b/include/cfree/link.h
@@ -112,9 +112,9 @@ typedef struct CfreeLinkScript {
uint32_t ntop_asns;
} CfreeLinkScript;
-CfreeStatus cfree_link_script_parse(const CfreeContext*, CfreeSlice text,
+CFREE_API CfreeStatus cfree_link_script_parse(const CfreeContext*, CfreeSlice text,
CfreeLinkScript** out);
-void cfree_link_script_free(const CfreeContext*, CfreeLinkScript*);
+CFREE_API void cfree_link_script_free(const CfreeContext*, CfreeLinkScript*);
typedef enum CfreeLinkMode {
CFREE_LM_DEFAULT,
@@ -184,19 +184,19 @@ typedef struct CfreeLinkSessionOptions {
const CfreeJitHost* jit_host;
} CfreeLinkSessionOptions;
-CfreeStatus cfree_link_session_new(CfreeCompiler*,
+CFREE_API CfreeStatus cfree_link_session_new(CfreeCompiler*,
const CfreeLinkSessionOptions*,
CfreeLinkSession** out);
-CfreeStatus cfree_link_session_add_obj(CfreeLinkSession*, CfreeObjBuilder*);
-CfreeStatus cfree_link_session_add_obj_bytes(CfreeLinkSession*, CfreeSlice name,
+CFREE_API CfreeStatus cfree_link_session_add_obj(CfreeLinkSession*, CfreeObjBuilder*);
+CFREE_API CfreeStatus cfree_link_session_add_obj_bytes(CfreeLinkSession*, CfreeSlice name,
const CfreeSlice*);
-CfreeStatus cfree_link_session_add_archive_bytes(CfreeLinkSession*,
+CFREE_API CfreeStatus cfree_link_session_add_archive_bytes(CfreeLinkSession*,
const CfreeLinkArchiveInput*);
-CfreeStatus cfree_link_session_add_dso_bytes(CfreeLinkSession*, CfreeSlice name,
+CFREE_API CfreeStatus cfree_link_session_add_dso_bytes(CfreeLinkSession*, CfreeSlice name,
const CfreeSlice*);
-CfreeStatus cfree_link_session_resolve(CfreeLinkSession*);
-CfreeStatus cfree_link_session_emit(CfreeLinkSession*, CfreeWriter* out);
-CfreeStatus cfree_link_session_jit(CfreeLinkSession*, CfreeJit** out_jit);
-void cfree_link_session_free(CfreeLinkSession*);
+CFREE_API CfreeStatus cfree_link_session_resolve(CfreeLinkSession*);
+CFREE_API CfreeStatus cfree_link_session_emit(CfreeLinkSession*, CfreeWriter* out);
+CFREE_API CfreeStatus cfree_link_session_jit(CfreeLinkSession*, CfreeJit** out_jit);
+CFREE_API void cfree_link_session_free(CfreeLinkSession*);
#endif
diff --git a/include/cfree/object.h b/include/cfree/object.h
@@ -119,60 +119,60 @@ typedef struct CfreeObjRelocDesc {
int64_t addend;
} CfreeObjRelocDesc;
-CfreeStatus cfree_obj_builder_new(CfreeCompiler *, CfreeObjBuilder **out);
-void cfree_obj_builder_free(CfreeObjBuilder *);
+CFREE_API CfreeStatus cfree_obj_builder_new(CfreeCompiler *, CfreeObjBuilder **out);
+CFREE_API void cfree_obj_builder_free(CfreeObjBuilder *);
/* Returns the CfreeCompiler this builder is bound to. Used by callers
* that hold a builder via cfree_obj_file_builder (the reader-side path)
* and need to intern strings into the matching Sym pool before issuing
* mutator calls. */
-CfreeCompiler *cfree_obj_builder_compiler(CfreeObjBuilder *);
+CFREE_API CfreeCompiler *cfree_obj_builder_compiler(CfreeObjBuilder *);
-CfreeStatus cfree_obj_builder_section(CfreeObjBuilder *,
+CFREE_API CfreeStatus cfree_obj_builder_section(CfreeObjBuilder *,
const CfreeObjSectionDesc *,
CfreeObjSection *out);
-CfreeStatus cfree_obj_builder_section_group(CfreeObjBuilder *, CfreeObjSection,
+CFREE_API CfreeStatus cfree_obj_builder_section_group(CfreeObjBuilder *, CfreeObjSection,
CfreeObjGroup);
-CfreeStatus cfree_obj_builder_pos(CfreeObjBuilder *, CfreeObjSection,
+CFREE_API CfreeStatus cfree_obj_builder_pos(CfreeObjBuilder *, CfreeObjSection,
uint64_t *out);
-CfreeStatus cfree_obj_builder_align(CfreeObjBuilder *, CfreeObjSection,
+CFREE_API CfreeStatus cfree_obj_builder_align(CfreeObjBuilder *, CfreeObjSection,
uint32_t align, uint64_t *new_pos_out);
-CfreeStatus cfree_obj_builder_write(CfreeObjBuilder *, CfreeObjSection,
+CFREE_API CfreeStatus cfree_obj_builder_write(CfreeObjBuilder *, CfreeObjSection,
const void *data, size_t n);
-CfreeStatus cfree_obj_builder_reserve(CfreeObjBuilder *, CfreeObjSection,
+CFREE_API CfreeStatus cfree_obj_builder_reserve(CfreeObjBuilder *, CfreeObjSection,
size_t n, void **out);
-CfreeStatus cfree_obj_builder_reserve_bss(CfreeObjBuilder *, CfreeObjSection,
+CFREE_API CfreeStatus cfree_obj_builder_reserve_bss(CfreeObjBuilder *, CfreeObjSection,
uint64_t size, uint32_t align);
-CfreeStatus cfree_obj_builder_patch(CfreeObjBuilder *, CfreeObjSection,
+CFREE_API CfreeStatus cfree_obj_builder_patch(CfreeObjBuilder *, CfreeObjSection,
uint64_t offset, const void *data,
size_t n);
-CfreeStatus cfree_obj_builder_symbol(CfreeObjBuilder *,
+CFREE_API CfreeStatus cfree_obj_builder_symbol(CfreeObjBuilder *,
const CfreeObjSymbolDesc *,
CfreeObjSymbol *out);
-CfreeStatus cfree_obj_builder_symbol_define(CfreeObjBuilder *, CfreeObjSymbol,
+CFREE_API CfreeStatus cfree_obj_builder_symbol_define(CfreeObjBuilder *, CfreeObjSymbol,
CfreeObjSection, uint64_t value,
uint64_t size);
-CfreeStatus cfree_obj_builder_reloc(CfreeObjBuilder *,
+CFREE_API CfreeStatus cfree_obj_builder_reloc(CfreeObjBuilder *,
const CfreeObjRelocDesc *);
-CfreeStatus cfree_obj_builder_group(CfreeObjBuilder *, CfreeSym name,
+CFREE_API CfreeStatus cfree_obj_builder_group(CfreeObjBuilder *, CfreeSym name,
CfreeObjSymbol signature, uint32_t flags,
CfreeObjGroup *out);
-CfreeStatus cfree_obj_builder_group_add_section(CfreeObjBuilder *,
+CFREE_API CfreeStatus cfree_obj_builder_group_add_section(CfreeObjBuilder *,
CfreeObjGroup,
CfreeObjSection);
-CfreeStatus cfree_obj_builder_finalize(CfreeObjBuilder *);
-CfreeStatus cfree_obj_builder_emit(CfreeObjBuilder *, CfreeWriter *);
+CFREE_API CfreeStatus cfree_obj_builder_finalize(CfreeObjBuilder *);
+CFREE_API CfreeStatus cfree_obj_builder_emit(CfreeObjBuilder *, CfreeWriter *);
/* Emit using a caller-specified output format instead of the builder's
* own target.obj. Used by `objcopy -O <bfdname>` to convert between
* ELF / Mach-O / COFF / Wasm at the same arch. Returns
* CFREE_UNSUPPORTED when the active arch doesn't have a backend for
* the requested format (e.g. RISC-V → Mach-O). */
-CfreeStatus cfree_obj_builder_emit_as(CfreeObjBuilder *, CfreeObjFmt,
+CFREE_API CfreeStatus cfree_obj_builder_emit_as(CfreeObjBuilder *, CfreeObjFmt,
CfreeWriter *);
/* ============================================================
@@ -188,19 +188,19 @@ CfreeStatus cfree_obj_builder_emit_as(CfreeObjBuilder *, CfreeObjFmt,
* mutation targets — the reader produces an already-finalized builder
* and mutators are legal on it.
*/
-CfreeStatus cfree_obj_builder_remove_section(CfreeObjBuilder *,
+CFREE_API CfreeStatus cfree_obj_builder_remove_section(CfreeObjBuilder *,
CfreeObjSection);
-CfreeStatus cfree_obj_builder_remove_symbol(CfreeObjBuilder *, CfreeObjSymbol);
-CfreeStatus cfree_obj_builder_remove_group(CfreeObjBuilder *, CfreeObjGroup);
-CfreeStatus cfree_obj_builder_rename_section(CfreeObjBuilder *,
+CFREE_API CfreeStatus cfree_obj_builder_remove_symbol(CfreeObjBuilder *, CfreeObjSymbol);
+CFREE_API CfreeStatus cfree_obj_builder_remove_group(CfreeObjBuilder *, CfreeObjGroup);
+CFREE_API CfreeStatus cfree_obj_builder_rename_section(CfreeObjBuilder *,
CfreeObjSection, CfreeSym new_name);
-CfreeStatus cfree_obj_builder_rename_symbol(CfreeObjBuilder *, CfreeObjSymbol,
+CFREE_API CfreeStatus cfree_obj_builder_rename_symbol(CfreeObjBuilder *, CfreeObjSymbol,
CfreeSym new_name);
-CfreeStatus cfree_obj_builder_symbol_set_bind(CfreeObjBuilder *,
+CFREE_API CfreeStatus cfree_obj_builder_symbol_set_bind(CfreeObjBuilder *,
CfreeObjSymbol, CfreeSymBind);
-CfreeStatus cfree_obj_builder_symbol_set_vis(CfreeObjBuilder *, CfreeObjSymbol,
+CFREE_API CfreeStatus cfree_obj_builder_symbol_set_vis(CfreeObjBuilder *, CfreeObjSymbol,
CfreeSymVis);
-CfreeStatus cfree_obj_builder_section_replace_bytes(CfreeObjBuilder *,
+CFREE_API CfreeStatus cfree_obj_builder_section_replace_bytes(CfreeObjBuilder *,
CfreeObjSection,
const void *data,
size_t n);
@@ -233,23 +233,23 @@ typedef struct CfreeObjGroupInfo {
const CfreeObjSection *sections;
} CfreeObjGroupInfo;
-CfreeBinFmt cfree_detect_fmt(const uint8_t *data, size_t len);
-CfreeStatus cfree_detect_target(const uint8_t *data, size_t len,
+CFREE_API CfreeBinFmt cfree_detect_fmt(const uint8_t *data, size_t len);
+CFREE_API CfreeStatus cfree_detect_target(const uint8_t *data, size_t len,
CfreeTarget *out);
-CfreeStatus cfree_obj_open(const CfreeContext *, CfreeSlice name,
+CFREE_API CfreeStatus cfree_obj_open(const CfreeContext *, CfreeSlice name,
const CfreeSlice *, CfreeObjFile **out);
-void cfree_obj_free(CfreeObjFile *);
+CFREE_API void cfree_obj_free(CfreeObjFile *);
-CfreeObjFmt cfree_obj_fmt(const CfreeObjFile *);
-CfreeTarget cfree_obj_target(const CfreeObjFile *);
+CFREE_API CfreeObjFmt cfree_obj_fmt(const CfreeObjFile *);
+CFREE_API CfreeTarget cfree_obj_target(const CfreeObjFile *);
-uint32_t cfree_obj_nsections(const CfreeObjFile *);
-CfreeStatus cfree_obj_section(const CfreeObjFile *, CfreeObjSection idx,
+CFREE_API uint32_t cfree_obj_nsections(const CfreeObjFile *);
+CFREE_API CfreeStatus cfree_obj_section(const CfreeObjFile *, CfreeObjSection idx,
CfreeObjSecInfo *out);
-CfreeStatus cfree_obj_section_data(const CfreeObjFile *, CfreeObjSection idx,
+CFREE_API CfreeStatus cfree_obj_section_data(const CfreeObjFile *, CfreeObjSection idx,
const uint8_t **data_out, size_t *len_out);
-CfreeStatus cfree_obj_section_by_name(const CfreeObjFile *, CfreeSlice name,
+CFREE_API CfreeStatus cfree_obj_section_by_name(const CfreeObjFile *, CfreeSlice name,
CfreeObjSection *out);
/* Format-specific raw section attributes preserved by the reader.
@@ -265,30 +265,30 @@ CfreeStatus cfree_obj_section_by_name(const CfreeObjFile *, CfreeSlice name,
* Use when canonical SecFlag/SecKind isn't enough — e.g. objdump
* decoding `IMAGE_SCN_LNK_COMDAT` / `_MEM_DISCARDABLE` for diagnostic
* display. NULL output pointers are ignored. */
-CfreeStatus cfree_obj_section_format_flags(const CfreeObjFile *,
+CFREE_API CfreeStatus cfree_obj_section_format_flags(const CfreeObjFile *,
CfreeObjSection idx,
uint32_t *raw_type_out,
uint32_t *raw_flags_out);
-CfreeStatus cfree_obj_symbol_by_name(const CfreeObjFile *, CfreeSlice name,
+CFREE_API CfreeStatus cfree_obj_symbol_by_name(const CfreeObjFile *, CfreeSlice name,
CfreeObjSymInfo *out);
-CfreeStatus cfree_obj_symiter_new(CfreeObjFile *, CfreeObjSymIter **out);
-CfreeIterResult cfree_obj_symiter_next(CfreeObjSymIter *,
+CFREE_API CfreeStatus cfree_obj_symiter_new(CfreeObjFile *, CfreeObjSymIter **out);
+CFREE_API CfreeIterResult cfree_obj_symiter_next(CfreeObjSymIter *,
CfreeObjSymInfo *out);
-void cfree_obj_symiter_free(CfreeObjSymIter *);
+CFREE_API void cfree_obj_symiter_free(CfreeObjSymIter *);
-CfreeStatus cfree_obj_reliter_new(CfreeObjFile *, CfreeObjRelocIter **out);
-CfreeIterResult cfree_obj_reliter_next(CfreeObjRelocIter *,
+CFREE_API CfreeStatus cfree_obj_reliter_new(CfreeObjFile *, CfreeObjRelocIter **out);
+CFREE_API CfreeIterResult cfree_obj_reliter_next(CfreeObjRelocIter *,
CfreeObjReloc *out);
-void cfree_obj_reliter_free(CfreeObjRelocIter *);
+CFREE_API void cfree_obj_reliter_free(CfreeObjRelocIter *);
/* Section-group iteration (ELF SHT_GROUP / COMDAT and friends). Empty
* for formats / objects that carry no groups. */
-CfreeStatus cfree_obj_groupiter_new(CfreeObjFile *, CfreeObjGroupIter **out);
-CfreeIterResult cfree_obj_groupiter_next(CfreeObjGroupIter *,
+CFREE_API CfreeStatus cfree_obj_groupiter_new(CfreeObjFile *, CfreeObjGroupIter **out);
+CFREE_API CfreeIterResult cfree_obj_groupiter_next(CfreeObjGroupIter *,
CfreeObjGroupInfo *out);
-void cfree_obj_groupiter_free(CfreeObjGroupIter *);
+CFREE_API void cfree_obj_groupiter_free(CfreeObjGroupIter *);
/* Roundtrip: open an object via cfree_obj_open, then hand its underlying
* builder back. The builder is the same one the reader populated; it is
@@ -301,6 +301,6 @@ void cfree_obj_groupiter_free(CfreeObjGroupIter *);
* symbol_set_* / section_replace_bytes calls above. Drops and renames
* are cheap field writes; emit applies the cascade (drop relocs against
* removed sections, etc.) automatically. */
-CfreeObjBuilder *cfree_obj_file_builder(const CfreeObjFile *);
+CFREE_API CfreeObjBuilder *cfree_obj_file_builder(const CfreeObjFile *);
#endif
diff --git a/include/cfree/preprocess.h b/include/cfree/preprocess.h
@@ -31,7 +31,7 @@ typedef struct CfreePreprocessOptions {
uint32_t nundefines;
} CfreePreprocessOptions;
-CfreeStatus cfree_cpp_preprocess(CfreeCompiler*, const CfreePreprocessOptions*,
+CFREE_API CfreeStatus cfree_cpp_preprocess(CfreeCompiler*, const CfreePreprocessOptions*,
CfreeSlice name, const CfreeSlice*,
CfreeWriter*);
diff --git a/include/cfree/source.h b/include/cfree/source.h
@@ -11,13 +11,13 @@
* dependency reporting and diagnostics.
*/
-CfreeStatus cfree_source_add_file(CfreeCompiler *, const char *path,
+CFREE_API CfreeStatus cfree_source_add_file(CfreeCompiler *, const char *path,
int system_header, uint32_t *file_id_out);
-CfreeStatus cfree_source_add_memory(CfreeCompiler *, CfreeSlice name,
+CFREE_API CfreeStatus cfree_source_add_memory(CfreeCompiler *, CfreeSlice name,
uint32_t *file_id_out);
-CfreeStatus cfree_source_add_builtin(CfreeCompiler *, CfreeSlice name,
+CFREE_API CfreeStatus cfree_source_add_builtin(CfreeCompiler *, CfreeSlice name,
uint32_t *file_id_out);
-CfreeStatus cfree_source_add_include(CfreeCompiler *, uint32_t includer_file_id,
+CFREE_API CfreeStatus cfree_source_add_include(CfreeCompiler *, uint32_t includer_file_id,
uint32_t included_file_id,
CfreeSrcLoc loc, int system);
@@ -30,7 +30,7 @@ typedef struct CfreeSourceFile {
uint16_t pad;
} CfreeSourceFile;
-CfreeStatus cfree_source_file(CfreeCompiler *, uint32_t file_id,
+CFREE_API CfreeStatus cfree_source_file(CfreeCompiler *, uint32_t file_id,
CfreeSourceFile *out);
#endif
diff --git a/include/cfree/support/arena.h b/include/cfree/support/arena.h
@@ -11,12 +11,12 @@
typedef struct CfreeArena CfreeArena;
-CfreeStatus cfree_arena_new(CfreeHeap *, size_t block_size, CfreeArena **out);
-void cfree_arena_free(CfreeArena *);
-void cfree_arena_reset(CfreeArena *);
-void *cfree_arena_alloc(CfreeArena *, size_t size, size_t align);
-void *cfree_arena_zalloc(CfreeArena *, size_t size, size_t align);
-char *cfree_arena_strdup(CfreeArena *, const char *s, size_t len);
+CFREE_API CfreeStatus cfree_arena_new(CfreeHeap *, size_t block_size, CfreeArena **out);
+CFREE_API void cfree_arena_free(CfreeArena *);
+CFREE_API void cfree_arena_reset(CfreeArena *);
+CFREE_API void *cfree_arena_alloc(CfreeArena *, size_t size, size_t align);
+CFREE_API void *cfree_arena_zalloc(CfreeArena *, size_t size, size_t align);
+CFREE_API char *cfree_arena_strdup(CfreeArena *, const char *s, size_t len);
#define cfree_arena_new_obj(a, T) \
((T *)cfree_arena_alloc((a), sizeof(T), _Alignof(T)))
diff --git a/test/test.mk b/test/test.mk
@@ -502,7 +502,8 @@ LIB_DEPS_ACTUAL = build/libcfree.deps.txt
LIB_RELOC = build/libcfree.reloc.o
LIB_RELOC_BAD = build/libcfree.reloc.bad-symbols.txt
-test-lib-deps: lib
+test-lib-deps:
+ @$(MAKE) lib RELEASE=1
@mkdir -p $(dir $(LIB_DEPS_ACTUAL))
@python3 scripts/lib_external_deps.py $(LIB_AR) > $(LIB_DEPS_ACTUAL)
@diff -u test/lib_deps.allowlist $(LIB_DEPS_ACTUAL) \