tinycc/tests/tests2/148_linker_symbols.c
grischka 64552b3faa
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-arm64-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
build and test / test-i386-linux (push) Has been cancelled
tccelf: rework linker_sym (_end/end) logic
- tcc_add_linker_symbols():
    don't add for dlls
- bind_exe_dynsym():
    update _end symbol when done
    allow data definition in the .so override a bss symbol
    in the exe. For example
       exe: int x;
       .so: int x = 123;
- set_elf_sym():
    cannot compare section numbers with symbols from dlls
  tcc_load_obj():
    return -1 from symbol conflict errors

tests/tests2/148_linker_symbols:
- use only one file
- make it print useful output rather than just "2 errors."
  In general, the tests2 setup with .expect files is meant
  to compare text output.  For example:
      printf("val = %d\n", val);

  .expect file can be generated or refreshed using
       make tests2.nnn+
   or in order to force generation with tcc itself
       make tests2.nnn+ GEN-CC='$(GEN-TCC)'

tccgen.c:
- __attribute__((section(...))) : set section type/flags
    according to first usage
- fix bcheck bounds for -fcommon
2026-08-05 17:41:23 +02:00

154 lines
3.8 KiB
C

int printf(const char *, ...);
#define assert(x) ((x) \
? (printf(" 1 (%s)\n",#x),1) \
: (printf("%s:%d: error: (%s)\n",__FILE__,__LINE__,#x),0))
#define O 100
#define SO 200
/* ------------------------------------------------------ */
#if TEST-O == 1
extern char etext[], _etext[];
extern char edata[], _edata[];
extern char end[], _end[];
int check_linker_symbols(void)
{
int errors = 0;
errors += !assert(etext == _etext);
errors += !assert(edata == _edata);
errors += !assert(end == _end);
return errors;
}
#elif TEST-MAIN == 1
int check_linker_symbols(void);
int main(void)
{
printf("linker symbols test\n");
assert(check_linker_symbols() == 0);
}
/* ------------------------------------------------------ */
#elif TEST-SO == 2
extern char etext[], edata[], end[];
void get_dso_end(char **p)
{
p[0] = etext;
p[1] = edata;
p[2] = end;
}
#elif TEST-MAIN == 2
extern char _etext[], _edata[], _end[];
extern void get_dso_end(char **);
static int fill_data = 123;
static int fill_bss;
int main(void)
{
char *p[3];
printf("DSO linker symbols test\n");
get_dso_end(p);
assert(p[0] == _etext) || printf("-- %p %p\n", p[0], _etext);
assert(p[1] == _edata) || printf("-- %p %p\n", p[1], _edata);
assert(p[2] == _end) || printf("-- %p %p\n", p[2], _end);
}
/* ------------------------------------------------------ */
#elif TEST-MAIN == 3
int etext(void) { return 1; }
int edata(void) { return 2; }
int end(void) { return 3; }
int main(void)
{
printf("user definition test\n");
assert(etext() + edata() + end() == 6);
}
/* ------------------------------------------------------ */
#elif TEST-SO == 4
unsigned char copy_reloc_data[257];
#elif TEST-MAIN == 4
extern unsigned char copy_reloc_data[257];
extern char end[], _end[];
int main(void)
{
unsigned long data_end;
printf("end copy relocation test\n");
copy_reloc_data[256] = 42;
data_end = (unsigned long)(copy_reloc_data + sizeof copy_reloc_data);
assert(end == _end);
assert((unsigned long)end >= data_end);
assert(copy_reloc_data[256] == 42);
}
/* ------------------------------------------------------ */
#elif TEST-O == 5
void __attribute__((section(".text.linker_test"), noinline, used))
linker_test_text(void)
{
}
__attribute__((section(".bss.linker_test"), used))
unsigned char linker_test_bss[257];
__attribute__((section(".data.linker_test"), used))
unsigned char linker_test_data[23] = { 1 };
#elif TEST-MAIN == 5
extern void linker_test_text(void);
extern unsigned char linker_test_data[23];
extern unsigned char linker_test_bss[257];
extern char etext[], _etext[];
extern char edata[], _edata[];
extern char end[], _end[];
int main(void)
{
char* text_addr = (void*)linker_test_text;
char* data_end = linker_test_data + sizeof linker_test_data;
char* bss_end = linker_test_bss + sizeof linker_test_bss;
printf("linker boundary test\n");
linker_test_data[22] = 42;
linker_test_bss[256] = 42;
assert(linker_test_bss > linker_test_data);
assert(etext == _etext);
assert(edata == _edata);
assert(end == _end);
assert(etext >= text_addr);
assert(edata >= data_end);
assert(end >= bss_end);
assert(linker_test_data[22] == 42);
assert(linker_test_bss[256] == 42);
}
/* ------------------------------------------------------ */
#elif TEST-SO == 6
int end;
int eight = 8;
int nine;
int dso_add() { return end + eight + nine; }
#elif TEST-MAIN == 6
int end = 7;
int eight;
int nine = 9;
int dso_add();
int main()
{
int sum;
printf("DSO initialized data test\n");
sum = dso_add();
assert(end == 7);
assert(eight == 8);
assert(nine == 9);
assert(sum == 24) || printf("-- %d + %d + %d = %d\n", end, eight, nine, sum);
}
/* ------------------------------------------------------ */
#endif