diff options
| author | grischka <grischka> | 2016-10-01 20:54:45 +0200 |
|---|---|---|
| committer | grischka <grischka> | 2016-10-01 20:54:45 +0200 |
| commit | 0d9f88ea6794edde6c752975be75d3d89c548d53 (patch) | |
| tree | 2e5e336b52f7adefe7f604f89c89ca48d2fc1246 /tccelf.c | |
| parent | 2f1174550e9b2356b7cebe9346858b1f1155520e (diff) | |
| download | tinycc-0d9f88ea6794edde6c752975be75d3d89c548d53.tar.gz tinycc-0d9f88ea6794edde6c752975be75d3d89c548d53.tar.bz2 | |
libtcc: reimplement option -Wl,[-no]-whöle-archive
- taking advantage of previous commit "incremental -Wl parsing"
Diffstat (limited to 'tccelf.c')
| -rw-r--r-- | tccelf.c | 43 |
1 files changed, 26 insertions, 17 deletions
@@ -2725,6 +2725,25 @@ typedef struct SectionMergeInfo { uint8_t link_once; /* true if link once section */ } SectionMergeInfo; +ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h) +{ + int size = read(fd, h, sizeof *h); + if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) { + if (h->e_type == ET_REL) + return AFF_BINTYPE_REL; + if (h->e_type == ET_DYN) + return AFF_BINTYPE_DYN; + } else if (size >= 8) { + if (0 == memcmp(h, ARMAG, 8)) + return AFF_BINTYPE_AR; +#ifdef TCC_TARGET_COFF + if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC) + return AFF_BINTYPE_C67; +#endif + } + return 0; +} + /* load an object file and merge it with current files */ /* XXX: handle correctly stab (debug) info */ ST_FUNC int tcc_load_object_file(TCCState *s1, @@ -2746,15 +2765,8 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, stab_index = stabstr_index = 0; - if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) - goto fail1; - if (ehdr.e_ident[0] != ELFMAG0 || - ehdr.e_ident[1] != ELFMAG1 || - ehdr.e_ident[2] != ELFMAG2 || - ehdr.e_ident[3] != ELFMAG3) - goto fail1; - /* test if object file */ - if (ehdr.e_type != ET_REL) + lseek(fd, file_offset, SEEK_SET); + if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL) goto fail1; /* test CPU specific stuff */ if (ehdr.e_ident[5] != ELFDATA2LSB || @@ -3052,7 +3064,6 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size) if(sym->st_shndx == SHN_UNDEF) { off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader); ++bound; - lseek(fd, off, SEEK_SET); if(tcc_load_object_file(s1, fd, off) < 0) { fail: ret = -1; @@ -3105,14 +3116,12 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd) /* coff symbol table : we handle it */ if(s1->alacarte_link) return tcc_load_alacarte(s1, fd, size); - } else if (!strcmp(ar_name, "//") || - !strcmp(ar_name, "__.SYMDEF") || - !strcmp(ar_name, "__.SYMDEF/") || - !strcmp(ar_name, "ARFILENAMES/")) { - /* skip symbol table or archive names */ } else { - if (tcc_load_object_file(s1, fd, file_offset) < 0) - return -1; + ElfW(Ehdr) ehdr; + if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) { + if (tcc_load_object_file(s1, fd, file_offset) < 0) + return -1; + } } lseek(fd, file_offset + size, SEEK_SET); } |
