History

Better handle ld scripts

* search file from INPUT and GROUP commands in the library path in addition to the current directory * handle libraries specified by -lfoo options * Search lib in GROUP command repeatedly

Thomas Preud'homme committed 16 years ago

Commit 47abdbd1 parent 6d4166d3 files · +136 −3Browse files

Unified · Split

3 files
  1. tcc.h +2 −0
  2. tccelf.c +113 −3
  3. tccpp.c +21 −0
tcc.h+2−0
@@ -225,6 +225,8 @@ typedef struct Sym { · 224 unmodified lines
225225 struct Sym *prev_tok; /* previous symbol for this token */
226226 } Sym;
227227
228+static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
229+
228230 /* section definition */
229231 /* XXX: use directly ELF structure for parameters ? */
230232 /* special flag to indicate that the section should not be linked to
tccelf.c+113−3
@@ -259,6 +259,7 @@ ST_FUNC int add_elf_sym(Section *s, uplong value, unsigned long size, · 258 unmodified lines
259259 do_patch:
260260 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
261261 esym->st_shndx = sh_num;
262+ new_undef_sym = 1;
262263 esym->st_value = value;
263264 esym->st_size = size;
264265 esym->st_other = other;
@@ -2808,9 +2809,77 @@ static int ld_next(TCCState *s1, char *name, int name_size) · 2543 unmodified lines
28082809 return c;
28092810 }
28102811
2812+/*
2813+ * Extract the library name from the file name
2814+ * Return 0 if the file isn't a library
2815+ *
2816+ * /!\ No test on filename capacity, be careful
2817+ */
2818+static int filename_to_libname(TCCState *s1, char filename[], char libname[])
2819+{
2820+ char *ext, *base;
2821+ int libprefix;
2822+
2823+ /* already converted to library name */
2824+ if (filename[0] == '\0')
2825+ return 1;
2826+ base = tcc_basename(filename);
2827+ if (base != filename)
2828+ return 0;
2829+ ext = strrchr(base, '.');
2830+ if (ext == NULL)
2831+ return 0;
2832+ ext++;
2833+ libprefix = !strncmp(filename, "lib", 3);
2834+ if (!s1->static_link) {
2835+#ifdef TCC_TARGET_PE
2836+ if (!strncmp(ext, "def", 3)) {
2837+ *(--ext) = '\0';
2838+ strcpy(libname, filename);
2839+ *ext = '.';
2840+ return 1;
2841+ }
2842+#else
2843+ if (libprefix && (!strncmp(ext, "so", 2))) {
2844+ *(--ext) = '\0';
2845+ strcpy(libname, filename + 3);
2846+ *ext = '.';
2847+ return 1;
2848+ }
2849+#endif
2850+ } else {
2851+ if (libprefix && (!strncmp(ext, "a", 1))) {
2852+ *(--ext) = '\0';
2853+ strcpy(libname, filename + 3);
2854+ *ext = '.';
2855+ return 1;
2856+ }
2857+ }
2858+ return 0;
2859+}
2860+
2861+/*
2862+ * Extract the file name from the library name
2863+ *
2864+ * /!\ No test on filename capacity, be careful
2865+ */
2866+static void libname_to_filename(TCCState *s1, char libname[], char filename[])
2867+{
2868+ if (!s1->static_link) {
2869+#ifdef TCC_TARGET_PE
2870+ snprintf(filename, strlen(libname) + 5, "%s.def", libname);
2871+#else
2872+ snprintf(filename, strlen(libname) + 7, "lib%s.so", libname);
2873+#endif
2874+ } else {
2875+ snprintf(filename, strlen(libname) + 6, "lib%s.a", libname);
2876+ }
2877+}
2878+
28112879 static int ld_add_file_list(TCCState *s1, int as_needed)
28122880 {
28132881 char filename[1024];
2882+ char libname[1024];
28142883 int t, ret;
28152884
28162885 t = ld_next(s1, filename, sizeof(filename));
@@ -2818,11 +2887,20 @@ static int ld_add_file_list(TCCState *s1, int as_needed) · 1 unmodified line
28182887 expect("(");
28192888 t = ld_next(s1, filename, sizeof(filename));
28202889 for(;;) {
2890+ libname[0] = '\0';
28212891 if (t == LD_TOK_EOF) {
28222892 error_noabort("unexpected end of file");
28232893 return -1;
28242894 } else if (t == ')') {
28252895 break;
2896+ } else if (t == '-') {
2897+ t = ld_next(s1, filename, sizeof(filename));
2898+ if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
2899+ error_noabort("library name expected");
2900+ return -1;
2901+ }
2902+ strcpy(libname, &filename[1]);
2903+ libname_to_filename(s1, libname, filename);
28262904 } else if (t != LD_TOK_NAME) {
28272905 error_noabort("filename expected");
28282906 return -1;
@@ -2833,8 +2911,15 @@ static int ld_add_file_list(TCCState *s1, int as_needed) · 4 unmodified lines
28332911 return ret;
28342912 } else {
28352913 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2836− if (!as_needed)
2837− tcc_add_file(s1, filename);
2914+ if (!as_needed) {
2915+ ret = tcc_add_file_internal(s1, filename, 0);
2916+ if (ret) {
2917+ if (filename_to_libname(s1, filename, libname))
2918+ ret = tcc_add_library(s1, libname);
2919+ if (ret)
2920+ return ret;
2921+ }
2922+ }
28382923 }
28392924 t = ld_next(s1, filename, sizeof(filename));
28402925 if (t == ',') {
@@ -2844,6 +2929,14 @@ static int ld_add_file_list(TCCState *s1, int as_needed) · 3 unmodified lines
28442929 return 0;
28452930 }
28462931
2932+static int new_undef_syms(void)
2933+{
2934+ int ret = 0;
2935+ ret = new_undef_sym;
2936+ new_undef_sym = 0;
2937+ return ret;
2938+}
2939+
28472940 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
28482941 files */
28492942 ST_FUNC int tcc_load_ldscript(TCCState *s1)
@@ -2862,7 +2955,24 @@ ST_FUNC int tcc_load_ldscript(TCCState *s1) · 12 unmodified lines
28622955 return -1;
28632956 if (!strcmp(cmd, "INPUT") ||
28642957 !strcmp(cmd, "GROUP")) {
2865− ret = ld_add_file_list(s1, 0);
2958+ if (!strcmp(cmd, "GROUP")) {
2959+ BufferedFile *buf_state;
2960+ int off;
2961+
2962+ buf_state = tcc_save_buffer_state(&off);
2963+ new_undef_syms();
2964+ ret = ld_add_file_list(s1, 0);
2965+ if (ret)
2966+ goto free_bufstate;
2967+ while (!ret && new_undef_syms()) {
2968+ tcc_load_buffer_state(buf_state, off);
2969+ ret = ld_add_file_list(s1, 0);
2970+ }
2971+ free_bufstate:
2972+ tcc_free_buffer_state(buf_state);
2973+ } else {
2974+ ret = ld_add_file_list(s1, 0);
2975+ }
28662976 if (ret)
28672977 return ret;
28682978 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
tccpp.c+21−0
@@ -378,6 +378,27 @@ static int tcc_peekc_slow(BufferedFile *bf) · 377 unmodified lines
378378 }
379379 }
380380
381+BufferedFile *tcc_save_buffer_state(int *offset)
382+{
383+ BufferedFile *state;
384+
385+ state = tcc_malloc(sizeof(BufferedFile));
386+ memcpy(state, file, sizeof(BufferedFile));
387+ *offset = lseek(file->fd, 0, SEEK_CUR);
388+ return state;
389+}
390+
391+void tcc_load_buffer_state(BufferedFile *buf_state, int offset)
392+{
393+ memcpy(file, buf_state, sizeof(BufferedFile));
394+ lseek(file->fd, offset, SEEK_SET);
395+}
396+
397+void tcc_free_buffer_state(BufferedFile *buf_state)
398+{
399+ tcc_free(buf_state);
400+}
401+
381402 /* return the current character, handling end of block if necessary
382403 (but not stray) */
383404 ST_FUNC int handle_eob(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