aboutsummaryrefslogtreecommitdiff
path: root/tccelf.c
diff options
context:
space:
mode:
authorgrischka <grischka>2016-10-01 20:54:45 +0200
committergrischka <grischka>2016-10-01 20:54:45 +0200
commit0d9f88ea6794edde6c752975be75d3d89c548d53 (patch)
tree2e5e336b52f7adefe7f604f89c89ca48d2fc1246 /tccelf.c
parent2f1174550e9b2356b7cebe9346858b1f1155520e (diff)
downloadtinycc-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.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/tccelf.c b/tccelf.c
index 33336c6..33ee076 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -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);
}