diff options
| author | Michael Matz <matz@suse.de> | 2016-10-14 16:44:41 +0200 |
|---|---|---|
| committer | Michael Matz <matz@suse.de> | 2016-10-14 16:47:43 +0200 |
| commit | c232af7ddbbf55055e0a47d9f0ca43dc6dd3d9de (patch) | |
| tree | 0b6b507486f3431760f97ac69a4310668641c130 | |
| parent | ed15cddacd145c74e4600af50f6616ba59ca0d8d (diff) | |
| download | tinycc-c232af7ddbbf55055e0a47d9f0ca43dc6dd3d9de.tar.gz tinycc-c232af7ddbbf55055e0a47d9f0ca43dc6dd3d9de.tar.bz2 | |
Support archives with 64 bit indices
Some systems started using SYM64 .a libraries, so start
supporting them.
| -rw-r--r-- | tccelf.c | 27 |
1 files changed, 20 insertions, 7 deletions
@@ -3037,10 +3037,17 @@ static int get_be32(const uint8_t *b) return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24); } +static long get_be64(const uint8_t *b) +{ + long long ret = get_be32(b); + ret = (ret << 32) | (unsigned)get_be32(b+4); + return (long)ret; +} + /* load only the objects which resolve undefined symbols */ -static int tcc_load_alacarte(TCCState *s1, int fd, int size) +static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize) { - int i, bound, nsyms, sym_index, off, ret; + long i, bound, nsyms, sym_index, off, ret; uint8_t *data; const char *ar_names, *p; const uint8_t *ar_index; @@ -3049,9 +3056,9 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size) data = tcc_malloc(size); if (read(fd, data, size) != size) goto fail; - nsyms = get_be32(data); - ar_index = data + 4; - ar_names = (char *) ar_index + nsyms * 4; + nsyms = entrysize == 4 ? get_be32(data) : get_be64(data); + ar_index = data + entrysize; + ar_names = (char *) ar_index + nsyms * entrysize; do { bound = 0; @@ -3060,7 +3067,10 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size) if(sym_index) { sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; if(sym->st_shndx == SHN_UNDEF) { - off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader); + off = (entrysize == 4 + ? get_be32(ar_index + i * 4) + : get_be64(ar_index + i * 8)) + + sizeof(ArchiveHeader); ++bound; if(tcc_load_object_file(s1, fd, off) < 0) { fail: @@ -3113,7 +3123,10 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd) if (!strcmp(ar_name, "/")) { /* coff symbol table : we handle it */ if(s1->alacarte_link) - return tcc_load_alacarte(s1, fd, size); + return tcc_load_alacarte(s1, fd, size, 4); + } else if (!strcmp(ar_name, "/SYM64/")) { + if(s1->alacarte_link) + return tcc_load_alacarte(s1, fd, size, 8); } else { ElfW(Ehdr) ehdr; if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) { |
