aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorseyko <seyko2@gmail.com>2016-05-20 15:12:32 +0300
committerseyko <seyko2@gmail.com>2016-05-20 15:12:32 +0300
commit19a169ceb896f78205bc23b847938c58f14d1dda (patch)
tree3bb430b5c22acf6c024749760d522c95c4c92b61
parent1339d0475954fa2278977562b618d9bab044bc82 (diff)
downloadtinycc-19a169ceb896f78205bc23b847938c58f14d1dda.tar.gz
tinycc-19a169ceb896f78205bc23b847938c58f14d1dda.tar.bz2
--whole-archive support
A patch is implemented as suggested in tinycc-devel mail list. From: Reuben Thomas Date: Thu, 31 Jul 2014 16:52:53 +0100 Subject: [PATCH] Add --{no,}-whole-archive support I resurrected the patch supplied to the mailing list in 2009 Since --whole-archive is a useful flag to get tcc working with autotools, and of course in its own right, I suggest you have a look at the patch and see if it is acceptable. I cannot see any suggestion that it was actively rejected last time round, just no evidence that it was ever added.
-rw-r--r--libtcc.c14
-rw-r--r--libtcc.h2
-rw-r--r--tcc-doc.texi8
-rw-r--r--tcc.c18
-rw-r--r--tcc.h1
-rw-r--r--tccelf.c3
6 files changed, 43 insertions, 3 deletions
diff --git a/libtcc.c b/libtcc.c
index b0fcdf9..a39bd5f 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -1406,9 +1406,11 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags,
ret = tcc_load_ldscript(s1);
#endif
if (ret < 0)
- tcc_error_noabort("unrecognized file type");
+ tcc_error_noabort("%s: unrecognized file type (error=%d)", filename, ret);
the_end:
+ if (s1->verbose)
+ printf("+> %s\n", filename);
tcc_close();
return ret;
}
@@ -2306,6 +2308,16 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv)
s->rdynamic = 1;
break;
case TCC_OPTION_Wl:
+ if (optarg && *optarg == '-') {
+ int offs = 0;
+ if (!strncmp("-no", optarg+1, 3))
+ offs += 3;
+ if (!strcmp("-whole-archive", optarg+1 + offs)) {
+ args_parser_add_file(s, "", (offs == 0) ? TCC_FILETYPE_AR_WHOLE_ON :
+ TCC_FILETYPE_AR_WHOLE_OFF);
+ break;
+ }
+ }
if (pas->linker_arg.size)
--pas->linker_arg.size, cstr_ccat(&pas->linker_arg, ',');
cstr_cat(&pas->linker_arg, optarg, 0);
diff --git a/libtcc.h b/libtcc.h
index 97b8587..8f39d19 100644
--- a/libtcc.h
+++ b/libtcc.h
@@ -53,6 +53,8 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename, int filetype);
#define TCC_FILETYPE_C 2
#define TCC_FILETYPE_ASM 3
#define TCC_FILETYPE_ASM_PP 4
+#define TCC_FILETYPE_AR_WHOLE_OFF 5
+#define TCC_FILETYPE_AR_WHOLE_ON 6
/* compile a string containing a C source. Return -1 if error. */
LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);
diff --git a/tcc-doc.texi b/tcc-doc.texi
index 4e26489..38b1f74 100644
--- a/tcc-doc.texi
+++ b/tcc-doc.texi
@@ -317,6 +317,14 @@ Generate an object file combining all input files.
@item -Wl,-rpath=path
Put custom seatch path for dynamic libraries into executable.
+@item -Wl,--whole-archive
+Add a whole archive, not just the symbols of the archive that would
+satisfy undefined symbols in the program.
+
+@item -Wl,--no-whole-archive
+Turn off the effect of the --whole-archive option for subsequent archive
+files.
+
@item -Wl,--oformat=fmt
Use @var{fmt} as output format. The supported output formats are:
@table @code
diff --git a/tcc.c b/tcc.c
index b340d9b..5e0a64a 100644
--- a/tcc.c
+++ b/tcc.c
@@ -247,6 +247,13 @@ static int64_t getclock_us(void)
#endif
}
+static void set_whole_archive(TCCState* s, int on)
+{
+ s->whole_archive = on;
+ if (1 == s->verbose)
+ printf("%cwhole-archive>\n", s->whole_archive? '+' : '-');
+}
+
int main(int argc, char **argv)
{
TCCState *s;
@@ -301,6 +308,14 @@ int main(int argc, char **argv)
for(i = ret = 0; i < s->nb_files && ret == 0; i++) {
int filetype = *(unsigned char *)s->files[i];
const char *filename = s->files[i] + 1;
+ if (filetype == TCC_FILETYPE_AR_WHOLE_ON ||
+ filetype == TCC_FILETYPE_AR_WHOLE_OFF)
+ {
+ set_whole_archive(s, filetype == TCC_FILETYPE_AR_WHOLE_ON);
+ continue;
+ }
+ if (1 == s->verbose)
+ printf("-> %s\n", filename);
if (filename[0] == '-' && filename[1] == 'l') {
if (tcc_add_library(s, filename + 2) < 0) {
/* don't fail on -lm as it's harmless to skip math lib */
@@ -310,8 +325,6 @@ int main(int argc, char **argv)
}
}
} else {
- if (1 == s->verbose)
- printf("-> %s\n", filename);
if (!s->outfile)
s->outfile = default_outputfile(s, filename);
if (tcc_add_file(s, filename, filetype) < 0)
@@ -335,6 +348,7 @@ int main(int argc, char **argv)
}
}
}
+ set_whole_archive(s, 0);
if (0 == ret) {
if (s->output_type == TCC_OUTPUT_MEMORY) {
diff --git a/tcc.h b/tcc.h
index 7b4481e..78d0b2d 100644
--- a/tcc.h
+++ b/tcc.h
@@ -692,6 +692,7 @@ struct TCCState {
int rdynamic; /* if true, all symbols are exported */
int symbolic; /* if true, resolve symbols in the current module first */
int alacarte_link; /* if true, only link in referenced objects from archive */
+ int whole_archive; /* if true, link in a whole *.a even when alacarte_link */
char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */
char *soname; /* as specified on the command line (-soname) */
diff --git a/tccelf.c b/tccelf.c
index 1ef4aef..2b50ff5 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -3076,6 +3076,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size)
if(sym_index) {
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
if(sym->st_shndx == SHN_UNDEF) {
+ load_obj:
off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
++bound;
lseek(fd, off, SEEK_SET);
@@ -3085,6 +3086,8 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size)
goto the_end;
}
}
+ } else if (s1->whole_archive) {
+ goto load_obj;
}
}
} while(bound);