>>> 2- once again, why not use the linker support for initialization?
>>>   If behavior has to depend on whether ECL was initialized yet,
>>>   the initialization could consider in calling ecl_register_init_function,
>>>   which depending on whether ECL was booted, would either call the function
>>>   and/or add it to a hook.
>>>   See once again attached files on how to use linker support for
>>>   initialization.
>>
>> Fact that we might bundle many objects in one archive doesn't mean that
>> they don't have dependencies on one another. *I think* that we have to
>> strictly control initialization order. It's possible that I'm wrong here
>> though.
>>
It *is* possible to strictly control initialization order while using
linker functions:
either ensure that you link objects in the correct order (duh),
and/or have your ensure_foo_initialized functions explicitly call each other.

>> Also do we want to *always* initialize *everything* what is linked? We
>> may have compiled-in support for number of lisp libraries in one module
>> just for conveniance and require them on demand depending on the
>> application using our code.
>>
There again, the linker-called code could "just" register the initialization
function to be called later, if that's what you want.

>> I'm guessing here since it's a design decision made by someone
>> else. Your proposition is surely worth investigating - it is like it is
>> because it was that way when I approached the codebase.
>>
Some decisions that might have made sense 30 years ago when C++
was a new thing and linkers didn't specially support constructors
don't make sense 30 years later when linkers do.

I'll attach my proof-of-concept code, that didn't make it to the list.

—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org
I'd rather write programs that write programs than write programs — Dick Sites
/*
gcc -W -Wall -Os -fPIC -Wl,-init,constructor1_init -shared -o constructor1.so constructor1.c &&
gcc -W -Wall -Os -o constructor0 constructor0.c -ldl &&
./constructor0
*/

#include <stdio.h>
#include <dlfcn.h>

#define SECTION( S ) __attribute__ ((section ( S )))

#pragma GCC diagnostic ignored "-Wunused-variable"

__asm__(".section .init \n call init0extern \n .section .text\n");
extern void init0extern(void) {
  printf ("init0extern\n");
}

static void ctor0static(void) {
   printf("ctor0static -- SHOULDN'T BE CALLED!\n");
}
static void (*ctor0static_ptr)(void) SECTION(".ctors") =ctor0static; // won't be called.

static void ctor0extern(void) {
   printf("ctor0extern\n");
}
/*extern*/ void (*ctor0extern_ptr)(void) SECTION(".ctors") =ctor0extern;

__attribute__((constructor (110)))
static void constructor0static110() {
  printf("constructor0static110\n");
}

__attribute__((constructor (130)))
static void constructor0static130() {
  printf("constructor0static130\n");
}

__attribute__((constructor (120)))
extern void constructor0extern120() {
  printf("constructor0extern120\n");
}

typedef void thunk(void);

static void constructor0static(void) {
  printf("constructor0static\n");
}
thunk* constructor0static_ptr = constructor0static;

extern int main (int argc, char** argv) {
  (void)argc; (void)argv;
  printf("Hello, World!\n");
  (*constructor0static_ptr)();
  void* dl = dlopen("./constructor1.so", RTLD_LOCAL|RTLD_NOW); // RTLD_GLOBAL|RTLD_NOW
  printf("dl = %p\n", dl);
  if (!dl) {
    printf("dlerror(): %s\n", dlerror());
  }
  thunk* c1 = (thunk*) dlsym(dl, "constructor1");
  printf("constructor1 = %p\n", c1);
  if (c1) {
    (*c1)();
  } else {
    printf("dlerror(): %s\n", dlerror());
  }
  return 0;
}
#include <stdio.h>

#define SECTION( S ) __attribute__ ((section ( S )))

#pragma GCC diagnostic ignored "-Wunused-variable"

static void init1static(void) {
  printf ("init1static\n");
}

static void init1static_caller(void) {
  __asm__(".section .init");
  init1static();
  __asm__(".section .text\n");
}


static void ctor1static(void) {
   printf("ctor1static -- SHOULDN'T BE CALLED!\n");
}
static void (*ctor1static_ptr)(void) SECTION(".ctors") =ctor1static; // won't be called.

static void ctor1extern(void) {
   printf("ctor1extern\n");
}
/*extern*/ void (*ctor1extern_ptr)(void) SECTION(".ctors") =ctor1extern;

__attribute__((constructor (111)))
static void constructor1static111(void) {
  printf("constructor1static111\n");
}

__attribute__((constructor (131)))
static void constructor1static131(void) {
  printf("constructor1static131\n");
}

__attribute__((constructor (121)))
extern void constructor1extern121(void) {
  printf("constructor1extern121\n");
}

extern void constructor1(void) {
  printf("constructor1\n");
}

extern void constructor1_init(void) {
  printf("constructor1_init\n");
}

Reply via email to