Skip to content

Commit

Permalink
fix: improve ldsoconf parser and use absolute paths
Browse files Browse the repository at this point in the history
the new_abspath function will convert any relative path into absolute
  • Loading branch information
jaromil committed Jan 3, 2025
1 parent fc2f600 commit ceab4be
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 42 deletions.
51 changes: 32 additions & 19 deletions src/cjit.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <libtcc.h>
#include <cwalk.h>
#include <array.h>

#include <elflinker.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h> // _err/_out
Expand Down Expand Up @@ -50,6 +50,9 @@ extern void win_compat_usleep(unsigned int microseconds);
extern ssize_t win_compat_getline(char **lineptr, size_t *n, FILE *stream);
extern bool get_winsdkpath(char *dst, size_t destlen);

// from file.c
extern char *new_abspath(const char *path);

static bool cjit_mkdtemp(CJITState *cjit) {
char tempDir[MAX_PATH];
#if defined(WINDOWS)
Expand Down Expand Up @@ -182,8 +185,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 @@ -213,16 +216,9 @@ static bool cjit_setup(CJITState *cjit) {
}
#endif

#if defined(LINUX)
{
xarray_t ldsoconf;
XArray_Init(&ldsoconf,3,0);
read_ldsoconf(&ldsoconf,"/etc/ld.so.conf.d");
int len = XArray_Used(&ldsoconf);
for(int i=0;i<len;i++) {
add(libpaths,XArray_GetData(&ldsoconf,i));
}
}
#if defined(POSIX)
read_ldsoconf(cjit->libpaths,"/etc/ld.so.conf");
read_ldsoconf_dir(cjit->libpaths,"/etc/ld.so.conf.d");
#endif

cjit->done_setup = true;
Expand Down Expand Up @@ -261,6 +257,9 @@ bool cjit_status(CJITState *cjit) {
#if !(defined TCC_TARGET_PE || defined TCC_TARGET_MACHO)
_err("ELF interpreter: %s",CONFIG_TCC_ELFINTERP);
#endif

////////////////////////
// call cjit_setup here
setup;
{
int i;
Expand All @@ -274,8 +273,10 @@ bool cjit_status(CJITState *cjit) {
used = XArray_Used(cjit->libpaths);
if(used) {
_err("Library paths (%u)",used);
for(i=0;i<used;i++)
_err("+ %s",XArray_GetData(cjit->libpaths,i));
for(i=0;i<used;i++) {
char *d = XArray_GetData(cjit->libpaths,i);
_err("+ %s",d?d:"(null)");
}
}
used = XArray_Used(cjit->libs);
if(used) {
Expand Down Expand Up @@ -592,14 +593,26 @@ void cjit_define_symbol(CJITState *cjit, const char *sym, const char *value) {
if(cjit->verbose)_err("+D %s %s",sym,value?value:"");
}
void cjit_add_include_path(CJITState *cjit, const char *path) {
tcc_add_include_path(tcc(cjit), path);
const char *restrict toadd = new_abspath(path);
if(!toadd) {
_err("%s: absolute path error: %s",__func__,path);
return;
}
tcc_add_include_path(tcc(cjit), toadd);
free(toadd);
debug("+I %s",path);
}
// TODO: temporary, to be reimplemented in linker.c
void cjit_add_library_path(CJITState *cjit, const char *path) {
tcc_add_library_path(tcc(cjit), path);
add(libpaths,path);
debug("+L %s",path);
const char *restrict toadd = new_abspath(path);
if(!toadd) {
_err("%s: absolute path error: %s",__func__,path);
return;
}
tcc_add_library_path(tcc(cjit), toadd);
add(libpaths,toadd);
free(toadd);
debug("+L %s",toadd);
}
// TODO: temporary, to be reimplemented in linker.c
void cjit_add_library(CJITState *cjit, const char *path) {
Expand Down
4 changes: 4 additions & 0 deletions src/cjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
#include <platforms.h>
#include <stdbool.h>

#if !defined(MAX_PATH)
#define MAX_PATH 512
#endif

// passed to cjit_exec with CJIT execution parameters
struct CJITState {
void *TCC; // the tinyCC context
Expand Down
53 changes: 32 additions & 21 deletions src/elflinker.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@
// interpret a subset of GNU ldscripts to handle dummy .so files

#include <platforms.h>
#if defined(LINUX)
#if defined(POSIX)
#define MAX_PATH 512
#include <cjit.h>
#include <elflinker.h>
#include <array.h>
#include <cwalk.h>
#include <elflinker.h>

#define CH_EOF (-1) //end of file
#define LD_TOK_NAME 256
Expand All @@ -38,6 +37,7 @@
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <dirent.h>
Expand All @@ -49,7 +49,29 @@ extern void dynarray_reset(void *pp, int *n);
extern char *tcc_strdup(const char *str);
extern char *pstrcpy(char *buf, size_t buf_size, const char *s);

bool read_ldsoconf(xarray_t *dest, const char *directory) {
bool read_ldsoconf(xarray_t *dest, char *path) {
FILE *file = fopen(path, "r");
if (!file) {
_err("%s: error opening file: %s",__func__,path);
_err("%s: %s",strerror(errno));
return false;
}
// TODO: optimize by allocating the buffer inside a xarray data
// struct to avoid double memcpy
char line[MAX_PATH];
while (fgets(line, MAX_PATH, file) != NULL) {
// Skip lines that aren't paths
if (line[0] != '/') continue;
size_t len = strlen(line);
if(line[len-1]=='\n') line[len-1]=0x0;
// add the line to the result array
XArray_AddData(dest,line,len+1);
}
fclose(file);
return true;
}

bool read_ldsoconf_dir(xarray_t *dest, const char *directory) {
DIR *dir;
struct dirent *entry;
char path[MAX_PATH];
Expand All @@ -63,23 +85,12 @@ bool read_ldsoconf(xarray_t *dest, const char *directory) {
cwk_path_join(directory,entry->d_name,path,MAX_PATH);
// Check if it's a regular file
if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
FILE *file = fopen(path, "r");
if (!file) {
_err("%s: error opening file: %s",__func__,path);
continue;
}
char line[512];
while (fgets(line, sizeof(line), file) != NULL) {
// Skip lines that are comments
if (line[0] != '/') continue;
size_t len = strlen(line);
if(line[len-1]=='\n') line[len-1]=0x0;
// add the line to the result array
XArray_AddData(dest,line,len);
}
fclose(file);
}
}
if(! read_ldsoconf(dest,path) ) {
_err("%s: Xarray_AddData error: %s",__func__,directory);
continue;
}
}
}
closedir(dir);
return true;
}
Expand Down
8 changes: 6 additions & 2 deletions src/elflinker.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#ifndef __LDSCRIPT_H__
#define __LDSCRIPT_H__
#ifndef __ELFLINKER_H__
#define __ELFLINKER_H__

#include <array.h>

struct LDState {
int cc;
Expand All @@ -9,6 +11,8 @@ struct LDState {
};
typedef struct LDState LDState;

bool read_ldsoconf(xarray_t *dest, char *path);
bool read_ldsoconf_dir(xarray_t *dest, const char *directory);
int cjit_load_ldscript(LDState *s1, char *path);

#endif
43 changes: 43 additions & 0 deletions src/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

#include <cjit.h>
#include <cwalk.h>

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -103,6 +104,48 @@ char *load_stdin() {
#endif
}

char *new_abspath(const char *path) {
char tpath[MAX_PATH];
char *res = NULL;
size_t len;
if(path[0]=='.' && path[1]==0x0) {
// argument is just .
if( getcwd(tpath,MAX_PATH) ) {
res = malloc(strlen(tpath)+1);
strcpy(res,tpath);
return(res);
}
}
if(path[0]=='.' && path[1]=='/') {
if( !getcwd(tpath,MAX_PATH) ) {
_err("%s: getcwd error: %s",__func__,strerror(errno));
return(NULL);
}
res = malloc(strlen(tpath)+1);
strcpy(res,tpath);
len = cwk_path_get_absolute(res,path,tpath,MAX_PATH);
res = realloc(res, len+1);
strcpy(res,tpath);
return(res);
}
if(path[0]!='/') {
if( !getcwd(tpath,MAX_PATH) ) {
_err("%s: getcwd error: %s",__func__,strerror(errno));
return(NULL);
}
res = malloc(strlen(tpath)+strlen(path)+16);
strcpy(res,tpath);
len = cwk_path_get_absolute(res,path,tpath,MAX_PATH);
res = realloc(res,len+1);
strcpy(res,tpath);
return(res);
}
len = cwk_path_normalize(path,tpath,MAX_PATH);
res = malloc(len+1);
strcpy(res,tpath);
return(res);
}

bool write_to_file(const char *path, const char *filename, const char *buf, unsigned int len) {
FILE *fd;
size_t written;
Expand Down

0 comments on commit ceab4be

Please sign in to comment.