History

alternative int tcc_relocate(TCCState *s1, void *ptr);

grischka committed 17 years ago

Commit 795f6741 parent 9a8b2913 files · +80 −74Browse files

Unified · Split

3 files
  1. libtcc.h +4 −3
  2. libtcc_test.c +16 −2
  3. tcc.c +60 −69
libtcc.h+4−3
@@ -84,9 +84,10 @@ int tcc_output_file(TCCState *s, const char *filename); · 83 unmodified lines
8484 tcc_relocate() before. */
8585 int tcc_run(TCCState *s, int argc, char **argv);
8686
87−/* do all relocations (needed before using tcc_get_symbol()). Return
88− non zero if link error. */
89−int tcc_relocate(TCCState *s);
87+/* copy code into memory passed in by the caller and do all relocations
88+ (needed before using tcc_get_symbol()).
89+ returns -1 on error and required size if ptr is NULL */
90+int tcc_relocate(TCCState *s1, void *ptr);
9091
9192 /* return symbol value. return 0 if OK, -1 if symbol not found */
9293 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name);
libtcc_test.c+16−2
@@ -36,6 +36,8 @@ int main(int argc, char **argv) · 35 unmodified lines
3636 TCCState *s;
3737 int (*func)(int);
3838 unsigned long val;
39+ void *mem;
40+ int size;
3941
4042 s = tcc_new();
4143 if (!s) {
@@ -53,13 +55,25 @@ int main(int argc, char **argv) · 11 unmodified lines
5355 with tcc_add_dll(() and using its symbols directly. */
5456 tcc_add_symbol(s, "add", (unsigned long)&add);
5557
56− tcc_relocate(s);
58+ /* get needed size of the code */
59+ size = tcc_relocate(s, NULL);
60+ if (size == -1)
61+ return 1;
5762
63+ /* allocate memory and copy the code into it */
64+ mem = malloc(size);
65+ tcc_relocate(s, mem);
66+
67+ /* get entry symbol */
5868 tcc_get_symbol(s, &val, "foo");
5969 func = (void *)val;
6070
71+ /* delete the state */
72+ tcc_delete(s);
73+
74+ /* run the code */
6175 func(32);
6276
63− tcc_delete(s);
77+ free(mem);
6478 return 0;
6579 }
tcc.c+60−69
@@ -542,6 +542,9 @@ struct TCCState { · 541 unmodified lines
542542
543543 /* output file for preprocessing */
544544 FILE *outfile;
545+
546+ /* for tcc_relocate */
547+ int runtime_added;
545548 };
546549
547550 /* The current value can be: */
@@ -10277,88 +10280,61 @@ static void sig_error(int signum, siginfo_t *siginf, void *puc) · 9729 unmodified lines
1027710280 }
1027810281 #endif
1027910282
10280−/* do all relocations (needed before using tcc_get_symbol()) */
10281−int tcc_relocate(TCCState *s1)
10283+/* copy code into memory passed in by the caller and do all relocations
10284+ (needed before using tcc_get_symbol()).
10285+ returns -1 on error and required size if ptr is NULL */
10286+int tcc_relocate(TCCState *s1, void *ptr)
1028210287 {
1028310288 Section *s;
10289+ unsigned long offset, length, mem;
1028410290 int i;
1028510291
1028610292 s1->nb_errors = 0;
10287−
10293+
10294+ if (0 == s1->runtime_added) {
1028810295 #ifdef TCC_TARGET_PE
10289− pe_add_runtime(s1);
10296+ pe_add_runtime(s1);
10297+ relocate_common_syms();
10298+ tcc_add_linker_symbols(s1);
1029010299 #else
10291− tcc_add_runtime(s1);
10292−#endif
10293−
10294− relocate_common_syms();
10295−
10296− tcc_add_linker_symbols(s1);
10297−#ifndef TCC_TARGET_PE
10298− build_got_entries(s1);
10300+ tcc_add_runtime(s1);
10301+ relocate_common_syms();
10302+ tcc_add_linker_symbols(s1);
10303+ build_got_entries(s1);
1029910304 #endif
10300−
10301−#ifdef TCC_TARGET_X86_64
10302− {
10303− /* If the distance of two sections are longer than 32bit, our
10304− program will crash. Let's combine all sections which are
10305− necessary to run the program into a single buffer in the
10306− text section */
10307− unsigned char *p;
10308− int size;
10309− /* calculate the size of buffers we need */
10310− size = 0;
10311− for(i = 1; i < s1->nb_sections; i++) {
10312− s = s1->sections[i];
10313− if (s->sh_flags & SHF_ALLOC) {
10314− size += s->data_offset;
10315− }
10316− }
10317− /* double the size of the buffer for got and plt entries
10318− XXX: calculate exact size for them? */
10319− section_realloc(text_section, size * 2);
10320− p = text_section->data + text_section->data_offset;
10321− /* we will put got and plt after this offset */
10322− text_section->data_offset = size;
10323−
10324− for(i = 1; i < s1->nb_sections; i++) {
10325− s = s1->sections[i];
10326− if (s->sh_flags & SHF_ALLOC) {
10327− if (s != text_section && s->data_offset) {
10328− if (s->sh_type == SHT_NOBITS) {
10329− /* for bss section */
10330− memset(p, 0, s->data_offset);
10331− } else {
10332− memcpy(p, s->data, s->data_offset);
10333− tcc_free(s->data);
10334− }
10335− s->data = p;
10336− /* we won't free s->data for this section */
10337− s->data_allocated = 0;
10338− p += s->data_offset;
10339− }
10340− s->sh_addr = (unsigned long)s->data;
10341− }
10342− }
10305+ s1->runtime_added = 1;
1034310306 }
10344−#else
10345− /* compute relocation address : section are relocated in place. We
10346− also alloc the bss space */
10307+
10308+ offset = 0;
10309+ mem = (unsigned long)ptr;
1034710310 for(i = 1; i < s1->nb_sections; i++) {
1034810311 s = s1->sections[i];
10349− if (s->sh_flags & SHF_ALLOC) {
10312+ if (0 == (s->sh_flags & SHF_ALLOC))
10313+ continue;
10314+ length = s->data_offset;
10315+ if (0 == mem) {
10316+ s->sh_addr = 0;
10317+ } else if (1 == mem) {
10318+ /* section are relocated in place.
10319+ We also alloc the bss space */
1035010320 if (s->sh_type == SHT_NOBITS)
10351− s->data = tcc_mallocz(s->data_offset);
10321+ s->data = tcc_malloc(length);
1035210322 s->sh_addr = (unsigned long)s->data;
10323+ } else {
10324+ /* sections are relocated to new memory */
10325+ s->sh_addr = (mem + offset + 15) & ~15;
1035310326 }
10327+ offset = (offset + length + 15) & ~15;
1035410328 }
10355−#endif
1035610329
10330+ /* relocate symbols */
1035710331 relocate_syms(s1, 1);
10358−
10359− if (s1->nb_errors != 0)
10332+ if (s1->nb_errors)
1036010333 return -1;
1036110334
10335+ if (0 == mem)
10336+ return offset + 15;
10337+
1036210338 /* relocate each section */
1036310339 for(i = 1; i < s1->nb_sections; i++) {
1036410340 s = s1->sections[i];
@@ -10366,12 +10342,20 @@ int tcc_relocate(TCCState *s1) · 1 unmodified line
1036610342 relocate_section(s1, s);
1036710343 }
1036810344
10369− /* mark executable sections as executable in memory */
1037010345 for(i = 1; i < s1->nb_sections; i++) {
1037110346 s = s1->sections[i];
10372− if ((s->sh_flags & (SHF_ALLOC | SHF_EXECINSTR)) ==
10373− (SHF_ALLOC | SHF_EXECINSTR))
10374− set_pages_executable(s->data, s->data_offset);
10347+ if (0 == (s->sh_flags & SHF_ALLOC))
10348+ continue;
10349+ length = s->data_offset;
10350+ // printf("%-12s %08x %04x\n", s->name, s->sh_addr, length);
10351+ ptr = (void*)s->sh_addr;
10352+ if (NULL == s->data || s->sh_type == SHT_NOBITS)
10353+ memset(ptr, 0, length);
10354+ else if (ptr != s->data)
10355+ memcpy(ptr, s->data, length);
10356+ /* mark executable sections as executable in memory */
10357+ if (s->sh_flags & SHF_EXECINSTR)
10358+ set_pages_executable(ptr, length);
1037510359 }
1037610360 return 0;
1037710361 }
@@ -10380,9 +10364,14 @@ int tcc_relocate(TCCState *s1) · 2 unmodified lines
1038010364 int tcc_run(TCCState *s1, int argc, char **argv)
1038110365 {
1038210366 int (*prog_main)(int, char **);
10367+ void *ptr;
10368+ int ret;
1038310369
10384− if (tcc_relocate(s1) < 0)
10370+ ret = tcc_relocate(s1, NULL);
10371+ if (ret < 0)
1038510372 return -1;
10373+ ptr = tcc_malloc(ret);
10374+ tcc_relocate(s1, ptr);
1038610375
1038710376 prog_main = tcc_get_symbol_err(s1, "main");
1038810377
@@ -10417,7 +10406,9 @@ int tcc_run(TCCState *s1, int argc, char **argv) · 28 unmodified lines
1041710406 bound_init();
1041810407 }
1041910408 #endif
10420− return (*prog_main)(argc, argv);
10409+ ret = (*prog_main)(argc, argv);
10410+ tcc_free(ptr);
10411+ return ret;
1042110412 }
1042210413
1042310414 void tcc_memstats(void)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t