History

tcc -vv ... : show objects loaded from archives

grischka committed 6 years ago

Commit 6082dd61 parent df349dd1 file · +65 −57Browse files

Unified · Split

tccelf.c+65−57
@@ -2795,59 +2795,78 @@ typedef struct ArchiveHeader { · 2794 unmodified lines
2795 char ar_fmag[2]; /* should contain ARFMAG */2795 char ar_fmag[2]; /* should contain ARFMAG */
2796} ArchiveHeader;2796} ArchiveHeader;
2797 2797
2798static int get_be32(const uint8_t *b)2798#define ARFMAG "`\n"
2799
2800static unsigned long long get_be(const uint8_t *b, int n)
2799{2801{
2800 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);2802 unsigned long long ret = 0;
2803 while (n)
2804 ret = (ret << 8) | *b++, --n;
2805 return ret;
2801}2806}
2802 2807
2803static long get_be64(const uint8_t *b)2808static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
2804{2809{
2805 long long ret = get_be32(b);2810 char *p, *e;
2806 ret = (ret << 32) | (unsigned)get_be32(b+4);2811 int len;
2807 return (long)ret;2812 lseek(fd, offset, SEEK_SET);
2813 len = full_read(fd, hdr, sizeof(ArchiveHeader));
2814 if (len != sizeof(ArchiveHeader))
2815 return len ? -1 : 0;
2816 p = hdr->ar_name;
2817 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
2818 --e;
2819 *e = '\0';
2820 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
2821 return len;
2808}2822}
2809 2823
2810/* load only the objects which resolve undefined symbols */2824/* load only the objects which resolve undefined symbols */
2811static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)2825static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2812{2826{
2813 long i, bound, nsyms, sym_index, off, ret;2827 int i, bound, nsyms, sym_index, len, ret = -1;
2828 unsigned long long off;
2814 uint8_t *data;2829 uint8_t *data;
2815 const char *ar_names, *p;2830 const char *ar_names, *p;
2816 const uint8_t *ar_index;2831 const uint8_t *ar_index;
2817 ElfW(Sym) *sym;2832 ElfW(Sym) *sym;
2818 Section *s;2833 ArchiveHeader hdr;
2819 2834
2820 data = tcc_malloc(size);2835 data = tcc_malloc(size);
2821 if (full_read(fd, data, size) != size)2836 if (full_read(fd, data, size) != size)
2822 goto fail;2837 goto the_end;
2823 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);2838 nsyms = get_be(data, entrysize);
2824 ar_index = data + entrysize;2839 ar_index = data + entrysize;
2825 ar_names = (char *) ar_index + nsyms * entrysize;2840 ar_names = (char *) ar_index + nsyms * entrysize;
2826 2841
2827 do {2842 do {
2828 bound = 0;2843 bound = 0;
2829 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {2844 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2830 s = symtab_section;2845 Section *s = symtab_section;
2831 sym_index = find_elf_sym(s, p);2846 sym_index = find_elf_sym(s, p);
2832 if(sym_index == 0) {2847#ifdef TCC_TARGET_PE /* windows DLL's don't have UNDEF syms */
2848 if (sym_index == 0) {
2833 s = s1->dynsymtab_section;2849 s = s1->dynsymtab_section;
2834 sym_index = find_elf_sym(s, p);2850 sym_index = find_elf_sym(s, p);
2835 }2851 }
2836 if(sym_index) {2852#endif
2837 sym = &((ElfW(Sym) *)s->data)[sym_index];2853 if (!sym_index)
2838 if(sym->st_shndx == SHN_UNDEF) {2854 continue;
2839 off = (entrysize == 42855 sym = &((ElfW(Sym) *)s->data)[sym_index];
2840 ? get_be32(ar_index + i * 4)2856 if(sym->st_shndx != SHN_UNDEF)
2841 : get_be64(ar_index + i * 8))2857 continue;
2842 + sizeof(ArchiveHeader);2858 off = get_be(ar_index + i * entrysize, entrysize);
2843 ++bound;2859 len = read_ar_header(fd, off, &hdr);
2844 if(tcc_load_object_file(s1, fd, off) < 0) {2860 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2845 fail:2861 tcc_error_noabort("invalid archive");
2846 ret = -1;2862 goto the_end;
2847 goto the_end;
2848 }
2849 }
2850 }2863 }
2864 off += len;
2865 if (s1->verbose == 2)
2866 printf(" -> %s\n", hdr.ar_name);
2867 if (tcc_load_object_file(s1, fd, off) < 0)
2868 goto the_end;
2869 ++bound;
2851 }2870 }
2852 } while(bound);2871 } while(bound);
2853 ret = 0;2872 ret = 0;
@@ -2860,52 +2879,41 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize) · 6 unmodified lines
2860ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)2879ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2861{2880{
2862 ArchiveHeader hdr;2881 ArchiveHeader hdr;
2863 char ar_size[11];2882 /* char magic[8]; */
2864 char ar_name[17];2883 int size, len;
2865 char magic[8];
2866 int size, len, i;
2867 unsigned long file_offset;2884 unsigned long file_offset;
2885 ElfW(Ehdr) ehdr;
2868 2886
2869 /* skip magic which was already checked */2887 /* skip magic which was already checked */
2870 full_read(fd, magic, sizeof(magic));2888 /* full_read(fd, magic, sizeof(magic)); */
2889 file_offset = sizeof ARMAG - 1;
2871 2890
2872 for(;;) {2891 for(;;) {
2873 len = full_read(fd, &hdr, sizeof(hdr));2892 len = read_ar_header(fd, file_offset, &hdr);
2874 if (len == 0)2893 if (len == 0)
2875 break;2894 return 0;
2876 if (len != sizeof(hdr)) {2895 if (len < 0) {
2877 tcc_error_noabort("invalid archive");2896 tcc_error_noabort("invalid archive");
2878 return -1;2897 return -1;
2879 }2898 }
2880 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));2899 file_offset += len;
2881 ar_size[sizeof(hdr.ar_size)] = '\0';2900 size = strtol(hdr.ar_size, NULL, 0);
2882 size = strtol(ar_size, NULL, 0);
2883 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2884 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2885 if (ar_name[i] != ' ')
2886 break;
2887 }
2888 ar_name[i + 1] = '\0';
2889 file_offset = lseek(fd, 0, SEEK_CUR);
2890 /* align to even */2901 /* align to even */
2891 size = (size + 1) & ~1;2902 size = (size + 1) & ~1;
2892 if (!strcmp(ar_name, "/")) {2903 if (alacarte) {
2893 /* coff symbol table : we handle it */2904 /* coff symbol table : we handle it */
2894 if (alacarte)2905 if (!strcmp(hdr.ar_name, "/"))
2895 return tcc_load_alacarte(s1, fd, size, 4);2906 return tcc_load_alacarte(s1, fd, size, 4);
2896 } else if (!strcmp(ar_name, "/SYM64/")) {2907 if (!strcmp(hdr.ar_name, "/SYM64/"))
2897 if (alacarte)
2898 return tcc_load_alacarte(s1, fd, size, 8);2908 return tcc_load_alacarte(s1, fd, size, 8);
2899 } else {2909 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2900 ElfW(Ehdr) ehdr;2910 if (s1->verbose == 2)
2901 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {2911 printf(" -> %s\n", hdr.ar_name);
2902 if (tcc_load_object_file(s1, fd, file_offset) < 0)2912 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2903 return -1;2913 return -1;
2904 }
2905 }2914 }
2906 lseek(fd, file_offset + size, SEEK_SET);2915 file_offset += size;
2907 }2916 }
2908 return 0;
2909}2917}
2910 2918
2911#ifndef ELF_OBJ_ONLY2919#ifndef ELF_OBJ_ONLY

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