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
225 struct Sym *prev_tok; /* previous symbol for this token */225 struct Sym *prev_tok; /* previous symbol for this token */
226} Sym;226} Sym;
227 227
228static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
229
228/* section definition */230/* section definition */
229/* XXX: use directly ELF structure for parameters ? */231/* XXX: use directly ELF structure for parameters ? */
230/* special flag to indicate that the section should not be linked to232/* 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
259 do_patch:259 do_patch:
260 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);260 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
261 esym->st_shndx = sh_num;261 esym->st_shndx = sh_num;
262 new_undef_sym = 1;
262 esym->st_value = value;263 esym->st_value = value;
263 esym->st_size = size;264 esym->st_size = size;
264 esym->st_other = other;265 esym->st_other = other;
@@ -2808,9 +2809,77 @@ static int ld_next(TCCState *s1, char *name, int name_size) · 2543 unmodified lines
2808 return c;2809 return c;
2809}2810}
2810 2811
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 */
2818static 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 */
2866static 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
2811static int ld_add_file_list(TCCState *s1, int as_needed)2879static int ld_add_file_list(TCCState *s1, int as_needed)
2812{2880{
2813 char filename[1024];2881 char filename[1024];
2882 char libname[1024];
2814 int t, ret;2883 int t, ret;
2815 2884
2816 t = ld_next(s1, filename, sizeof(filename));2885 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
2818 expect("(");2887 expect("(");
2819 t = ld_next(s1, filename, sizeof(filename));2888 t = ld_next(s1, filename, sizeof(filename));
2820 for(;;) {2889 for(;;) {
2890 libname[0] = '\0';
2821 if (t == LD_TOK_EOF) {2891 if (t == LD_TOK_EOF) {
2822 error_noabort("unexpected end of file");2892 error_noabort("unexpected end of file");
2823 return -1;2893 return -1;
2824 } else if (t == ')') {2894 } else if (t == ')') {
2825 break;2895 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);
2826 } else if (t != LD_TOK_NAME) {2904 } else if (t != LD_TOK_NAME) {
2827 error_noabort("filename expected");2905 error_noabort("filename expected");
2828 return -1;2906 return -1;
@@ -2833,8 +2911,15 @@ static int ld_add_file_list(TCCState *s1, int as_needed) · 4 unmodified lines
2833 return ret;2911 return ret;
2834 } else {2912 } else {
2835 /* TODO: Implement AS_NEEDED support. Ignore it for now */2913 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2836 if (!as_needed)2914 if (!as_needed) {
2837 tcc_add_file(s1, filename);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 }
2838 }2923 }
2839 t = ld_next(s1, filename, sizeof(filename));2924 t = ld_next(s1, filename, sizeof(filename));
2840 if (t == ',') {2925 if (t == ',') {
@@ -2844,6 +2929,14 @@ static int ld_add_file_list(TCCState *s1, int as_needed) · 3 unmodified lines
2844 return 0;2929 return 0;
2845}2930}
2846 2931
2932static 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
2847/* interpret a subset of GNU ldscripts to handle the dummy libc.so2940/* interpret a subset of GNU ldscripts to handle the dummy libc.so
2848 files */2941 files */
2849ST_FUNC int tcc_load_ldscript(TCCState *s1)2942ST_FUNC int tcc_load_ldscript(TCCState *s1)
@@ -2862,7 +2955,24 @@ ST_FUNC int tcc_load_ldscript(TCCState *s1) · 12 unmodified lines
2862 return -1;2955 return -1;
2863 if (!strcmp(cmd, "INPUT") ||2956 if (!strcmp(cmd, "INPUT") ||
2864 !strcmp(cmd, "GROUP")) {2957 !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 }
2866 if (ret)2976 if (ret)
2867 return ret;2977 return ret;
2868 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||2978 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
tccpp.c+21−0
@@ -378,6 +378,27 @@ static int tcc_peekc_slow(BufferedFile *bf) · 377 unmodified lines
378 }378 }
379}379}
380 380
381BufferedFile *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
391void 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
397void tcc_free_buffer_state(BufferedFile *buf_state)
398{
399 tcc_free(buf_state);
400}
401
381/* return the current character, handling end of block if necessary402/* return the current character, handling end of block if necessary
382 (but not stray) */403 (but not stray) */
383ST_FUNC int handle_eob(void)404ST_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