Skip to content

Commit

Permalink
fix: linking shared libs and test on linux
Browse files Browse the repository at this point in the history
  • Loading branch information
jaromil committed Jan 5, 2025
1 parent cb86d1c commit c8a1fbb
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 23 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,6 @@ jobs:
runs-on: "ubuntu-latest"
steps:
- uses: actions/checkout@v4
- name: install dependencies
run: |
sudo apt install -yq make gcc xxd
- name: Build x86_64 with Linux
run: |
make linux-x86
Expand Down
5 changes: 4 additions & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,19 @@ _: ##

check: ## 🧪 Run all tests using the currently built binary ./cjit
@./test/bats/bin/bats test/cli.bats
@if [ -r .build_done_linux ]; then ./test/bats/bin/bats test/linux.bats; fi
@./test/bats/bin/bats test/windows.bats
@./test/bats/bin/bats test/muntar.bats
@if [ -r .build_done_linux ]; then ./test/bats/bin/bats test/dmon.bats; fi


check-ci: ## 🧪 Run all tests using the currently built binary ./cjit
@./test/bats/bin/bats test/cli.bats
@if [ -r .build_done_linux ]; then ./test/bats/bin/bats test/linux.bats; fi
@./test/bats/bin/bats test/windows.bats
@./test/bats/bin/bats test/muntar.bats

# dmon filesystem monitoring doesn't works in CI

_: ##
clean: ## 🧹 Clean the source from all built objects
$(MAKE) -f build/deps.mk clean
Expand Down
23 changes: 17 additions & 6 deletions src/cjit.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@ static bool cjit_setup(CJITState *cjit) {
}
}
tcc_add_sysinclude_path(tcc(cjit), cjit->tmpdir);
// tcc_add_sysinclude_path(tcc(cjit), ".");
// tcc_add_sysinclude_path(tcc(cjit), "include"); // TODO: check if exists
tcc_add_sysinclude_path(tcc(cjit), ".");
tcc_add_sysinclude_path(tcc(cjit), "include"); // TODO: check if exists

#if defined(WINDOWS)
{
Expand Down Expand Up @@ -294,13 +294,15 @@ bool cjit_status(CJITState *cjit) {
for(int i=0;i<used;i++)
_err("+ %s",XArray_GetData(cjit->libs,i));
}
#if defined(UNIX)
resolve_libs(cjit);
used = XArray_Used(cjit->reallibs);
if(used) {
_err("Lib files (%u)",used);
for(int i=0;i<used;i++)
_err("+ %s",XArray_GetData(cjit->reallibs,i));
}
#endif

}
return true;
Expand Down Expand Up @@ -404,7 +406,11 @@ bool cjit_add_source(CJITState *cjit, const char *path) {
}
strcpy(contents,spath);
free(spath);
fread(contents+spath_len, 1, length, file);
if(0== fread(contents+spath_len, 1, length, file)) {
fail(file);
fclose(file);
return false;
}
contents[length+spath_len] = 0x0;
fclose(file);
{ // if inside a dir then add dir to includes too
Expand Down Expand Up @@ -517,7 +523,6 @@ int cjit_exec(CJITState *cjit, int argc, char **argv) {
for(int i=0;i<found;i++) {
char *f = XArray_GetData(cjit->reallibs,i);
if(f) {
_err("%i add file: %s",i, f);
tcc_add_file(tcc(cjit), f);
}
}
Expand Down Expand Up @@ -624,15 +629,21 @@ void cjit_add_library_path(CJITState *cjit, const char *path) {
_err("%s: absolute path error: %s",__func__,path);
return;
}
tcc_add_library_path(tcc(cjit), toadd);
#if defined(UNIX)
add(libpaths,toadd);
#else
tcc_add_library_path(tcc(cjit), toadd);
#endif
debug("+L %s",toadd);
free(toadd);
}
// TODO: temporary, to be reimplemented in linker.c
void cjit_add_library(CJITState *cjit, const char *path) {
tcc_add_library(tcc(cjit), path);
#if defined(UNIX)
add(libs,path);
#else
tcc_add_library(tcc(cjit), path);
#endif
debug("+l %s",path);
}
void cjit_set_tcc_options(CJITState *cjit, const char *opts) {
Expand Down
6 changes: 3 additions & 3 deletions src/elflinker.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ int resolve_libs(CJITState *cjit) {
break;
}
}
if(found!=0)
_err("Library not found: lib%s.so",lname);
// continue anyway (will log missing symbol names)
}
return(XArray_Used(cjit->reallibs));
}
Expand All @@ -146,14 +149,12 @@ static int find_library(xarray_t *results, const char *path) {
return -1;
}
tpath[len] = 0x0;
_err("symlink to: %s (%i)",tpath,len);
size_t rlen = tlen + len;
reallib = malloc(rlen+1); // ALLOC
cwk_path_get_dirname(path,&rlen);
memcpy(reallib,path,rlen);
strcpy(&reallib[rlen],tpath);
free(tpath); // FREE tpath
// _err("symlink to: %s",reallib);
} else if (S_ISREG(statbuf.st_mode)) {
reallib = malloc(strlen(path)+1); // ALLOC
strcpy(reallib,path);
Expand All @@ -162,7 +163,6 @@ static int find_library(xarray_t *results, const char *path) {
_err("%s: internal error: %s",__func__,path);
return -1;
}
_err("reallib: %s",reallib);
FILE *fd = fopen(reallib,"r");
if(!fd) {
free(reallib);
Expand Down
106 changes: 96 additions & 10 deletions test/linux.bats
Original file line number Diff line number Diff line change
@@ -1,17 +1,103 @@
load bats_setup

@test "linker resolution of simple gnu ld scripts" {
@test "Log ldso.conf.d output and libc.so resolution" {
${CJIT} -DVERSION=debug -lc -v 2>&3
}

@test "Linker resolution of libm simple gnu ld script" {
cat << EOF > ldscript_test.c
#include <linker.h>
int main(int argc, char **argv) {
LDState s1;
int res;
res = cjit_load_ldscript(&s1,"/usr/lib/x86_64-linux-gnu/libm.so");
return(res);
#include <stdio.h>
#include <math.h>
int solve_quadratic(double a, double b, double c) {
double discriminant = b * b - 4 * a * c;
// Check if the discriminant is non-negative
if (discriminant < 0) {
printf("No real roots exist.\n");
return 1;
}
double sqrt_discriminant = sqrt(discriminant);
double root1 = (-b + sqrt_discriminant) / (2 * a);
double root2 = (-b - sqrt_discriminant) / (2 * a);
printf("Roots: %.2f and %.2f\n", root1, root2);
return 0;
}
int main() {
double a, b, c;
// x^2 - 3x + 2 = 0
a = 1.0;
b = -3.0;
c = 2.0;
// Solve the quadratic equation
return solve_quadratic(a, b, c);
}
EOF
run ${CJIT} -DVERSION=debug ldscript_test.c -lm
assert_success
assert_output 'Roots: 2.00 and 1.00'
}

@test "Linker resolution of openssl" {
echo "Hello World!" | base64 > ${TMP}/hello.b64
cat << EOF > base64_hello.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
// Function to decode base64 using OpenSSL
unsigned char *base64_decode(const char *input, int *output_len) {
BIO *bio, *b64;
int input_len = strlen(input);
unsigned char *output = (unsigned char *)malloc((input_len * 3) / 4);
if (!output) {
perror("malloc");
return NULL; }
bio = BIO_new_mem_buf(input, input_len);
if (!bio) {
perror("BIO_new_mem_buf");
free(output);
return NULL; }
b64 = BIO_new(BIO_f_base64());
if (!b64) {
perror("BIO_new");
BIO_free(bio);
free(output);
return NULL; }
bio = BIO_push(b64, bio);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
// Do not use newlines to flush buffer
*output_len = BIO_read(bio, output, input_len);
if (*output_len < 0) {
perror("BIO_read");
BIO_free_all(bio);
free(output);
return NULL; }
BIO_free_all(bio);
return output;
}
int main(int argc, char *argv[]) {
if (argc != 2) return 1;
char *input = argv[1];
int decoded_len;
unsigned char *decoded = base64_decode(input, &decoded_len);
if (!decoded) {
fprintf(stderr, "Decoding base64 failed.\n");
return 1; }
fwrite(decoded, 1, decoded_len, stdout);
printf("\n");
free(decoded);
return 0;
}
EOF
run ${CJIT} -DVERSION=debug --verb ldscript_test.c \
-I ${R}/src ${R}/src/cjit.c ${R}/src/linker.c \
${R}/lib/tinycc/libtcc.a
run ${CJIT} -DVERSION=debug base64_hello.c -lssl \
-- `cat ${TMP}/hello.b64`
assert_success
assert_output 'Hello World!'
}

@test "Linker missing library" {
run ${CJIT} -DVERSION=debug -l hyeronimus_bartolomeus test/hello.c
assert_success
assert_line 'Library not found: libhyeronimus_bartolomeus.so'
}

0 comments on commit c8a1fbb

Please sign in to comment.