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
27952795 char ar_fmag[2]; /* should contain ARFMAG */
27962796 } ArchiveHeader;
27972797
2798−static int get_be32(const uint8_t *b)
2798+#define ARFMAG "`\n"
2799+
2800+static unsigned long long get_be(const uint8_t *b, int n)
27992801 {
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;
28012806 }
28022807
2803−static long get_be64(const uint8_t *b)
2808+static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
28042809 {
2805− long long ret = get_be32(b);
2806− ret = (ret << 32) | (unsigned)get_be32(b+4);
2807− return (long)ret;
2810+ char *p, *e;
2811+ int len;
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;
28082822 }
28092823
28102824 /* load only the objects which resolve undefined symbols */
28112825 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
28122826 {
2813− long i, bound, nsyms, sym_index, off, ret;
2827+ int i, bound, nsyms, sym_index, len, ret = -1;
2828+ unsigned long long off;
28142829 uint8_t *data;
28152830 const char *ar_names, *p;
28162831 const uint8_t *ar_index;
28172832 ElfW(Sym) *sym;
2818− Section *s;
2833+ ArchiveHeader hdr;
28192834
28202835 data = tcc_malloc(size);
28212836 if (full_read(fd, data, size) != size)
2822− goto fail;
2823− nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
2837+ goto the_end;
2838+ nsyms = get_be(data, entrysize);
28242839 ar_index = data + entrysize;
28252840 ar_names = (char *) ar_index + nsyms * entrysize;
28262841
28272842 do {
28282843 bound = 0;
2829− for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2830− s = symtab_section;
2844+ for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2845+ Section *s = symtab_section;
28312846 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) {
28332849 s = s1->dynsymtab_section;
28342850 sym_index = find_elf_sym(s, p);
28352851 }
2836− if(sym_index) {
2837− sym = &((ElfW(Sym) *)s->data)[sym_index];
2838− if(sym->st_shndx == SHN_UNDEF) {
2839− off = (entrysize == 4
2840− ? get_be32(ar_index + i * 4)
2841− : get_be64(ar_index + i * 8))
2842− + sizeof(ArchiveHeader);
2843− ++bound;
2844− if(tcc_load_object_file(s1, fd, off) < 0) {
2845− fail:
2846− ret = -1;
2847− goto the_end;
2848− }
2849− }
2852+#endif
2853+ if (!sym_index)
2854+ continue;
2855+ sym = &((ElfW(Sym) *)s->data)[sym_index];
2856+ if(sym->st_shndx != SHN_UNDEF)
2857+ continue;
2858+ off = get_be(ar_index + i * entrysize, entrysize);
2859+ len = read_ar_header(fd, off, &hdr);
2860+ if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2861+ tcc_error_noabort("invalid archive");
2862+ goto the_end;
28502863 }
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;
28512870 }
28522871 } while(bound);
28532872 ret = 0;
@@ -2860,52 +2879,41 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize) · 6 unmodified lines
28602879 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
28612880 {
28622881 ArchiveHeader hdr;
2863− char ar_size[11];
2864− char ar_name[17];
2865− char magic[8];
2866− int size, len, i;
2882+ /* char magic[8]; */
2883+ int size, len;
28672884 unsigned long file_offset;
2885+ ElfW(Ehdr) ehdr;
28682886
28692887 /* 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;
28712890
28722891 for(;;) {
2873− len = full_read(fd, &hdr, sizeof(hdr));
2892+ len = read_ar_header(fd, file_offset, &hdr);
28742893 if (len == 0)
2875− break;
2876− if (len != sizeof(hdr)) {
2894+ return 0;
2895+ if (len < 0) {
28772896 tcc_error_noabort("invalid archive");
28782897 return -1;
28792898 }
2880− memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2881− ar_size[sizeof(hdr.ar_size)] = '\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);
2899+ file_offset += len;
2900+ size = strtol(hdr.ar_size, NULL, 0);
28902901 /* align to even */
28912902 size = (size + 1) & ~1;
2892− if (!strcmp(ar_name, "/")) {
2903+ if (alacarte) {
28932904 /* coff symbol table : we handle it */
2894− if (alacarte)
2905+ if (!strcmp(hdr.ar_name, "/"))
28952906 return tcc_load_alacarte(s1, fd, size, 4);
2896− } else if (!strcmp(ar_name, "/SYM64/")) {
2897− if (alacarte)
2907+ if (!strcmp(hdr.ar_name, "/SYM64/"))
28982908 return tcc_load_alacarte(s1, fd, size, 8);
2899− } else {
2900− ElfW(Ehdr) ehdr;
2901− if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2902− if (tcc_load_object_file(s1, fd, file_offset) < 0)
2903− return -1;
2904− }
2909+ } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2910+ if (s1->verbose == 2)
2911+ printf(" -> %s\n", hdr.ar_name);
2912+ if (tcc_load_object_file(s1, fd, file_offset) < 0)
2913+ return -1;
29052914 }
2906− lseek(fd, file_offset + size, SEEK_SET);
2915+ file_offset += size;
29072916 }
2908− return 0;
29092917 }
29102918
29112919 #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