Skip to content

Commit

Permalink
tcc -ar: pad archive member position to even
Browse files Browse the repository at this point in the history
Since commit 45cff8f tcc eventually generates object files
of non-even size.

tccelf.c:
- check ARFMAG for better invalid archive detection
- file_offset needs to be aligned, not the size (just a nitpick)
lib/Makefile:
- remake everything when tcc did change
  • Loading branch information
grischka committed Oct 22, 2024
1 parent d7f9166 commit 9fb89c2
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 12 deletions.
21 changes: 14 additions & 7 deletions lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib
T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)

TCC = $(TOP)/$(X)tcc$(EXESUF)
XTCC ?= $(TOP)/$(X)tcc$(EXESUF)
XCC = $(XTCC)
XAR = $(XTCC) -ar
Expand Down Expand Up @@ -44,6 +45,9 @@ $(X)BT_O += runmain.o tcov.o

DSO_O = dsohandle.o

# not in libtcc1.a
EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o

I386_O = libtcc1.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o $(BT_O)
X86_64_O = libtcc1.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o $(BT_O)
ARM_O = libtcc1.o armeabi.o alloca.o armflush.o stdatomic.o atomic.o builtin.o $(BT_O)
Expand All @@ -67,23 +71,23 @@ OBJ-arm-eabihf = $(ARM_O) $(DSO_O)
OBJ-arm-wince = $(ARM_O) $(WIN_O)
OBJ-riscv64 = $(RISCV64_O) $(BCHECK_O) $(DSO_O)

OBJ-extra = $(filter $(B_O) runmain.o,$(OBJ-$T))
OBJ-extra = $(filter $(EXTRA_O),$(OBJ-$T))
OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T)))

ALL = $(addprefix $(TOP)/,$(X)libtcc1.a $(OBJ-extra))

all: $(ALL)

$(TOP)/$(X)libtcc1.a : $(OBJ-libtcc1)
$S$(XAR) rcs $@ $^
$(TOP)/$(X)libtcc1.a : $(OBJ-libtcc1) $(TCC)
$S$(XAR) rcs $@ $(OBJ-libtcc1)

$(X)%.o : %.c
$(X)%.o : %.c $(TCC)
$S$(XCC) -c $< -o $@ $(XFLAGS)

$(X)%.o : %.S
$(X)%.o : %.S $(TCC)
$S$(XCC) -c $< -o $@ $(XFLAGS)

$(TOP)/%.o : %.c
$(TOP)/%.o : %.c $(TCC)
$S$(XCC) -c $< -o $@ $(XFLAGS)

$(TOP)/bcheck.o : XFLAGS += $(BFLAGS) $(if $(CONFIG_musl),-DTCC_MUSL)
Expand All @@ -92,5 +96,8 @@ $(TOP)/bt-exe.o : $(TOP)/tccrun.c
$(X)crt1w.o : crt1.c
$(X)wincrt1w.o : wincrt1.c

# don't try to make it
$(TCC) : ;

clean :
rm -f *.a *.o $(ALL)
rm -f *.o $(addprefix $(TOP)/,*libtcc1.a $(EXTRA_O))
7 changes: 4 additions & 3 deletions tccelf.c
Original file line number Diff line number Diff line change
Expand Up @@ -3374,6 +3374,8 @@ static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
len = full_read(fd, hdr, sizeof(ArchiveHeader));
if (len != sizeof(ArchiveHeader))
return len ? -1 : 0;
if (memcmp(hdr->ar_fmag, ARFMAG, sizeof hdr->ar_fmag))
return -1;
p = hdr->ar_name;
for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
--e;
Expand Down Expand Up @@ -3451,8 +3453,6 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
return tcc_error_noabort("invalid archive");
file_offset += len;
size = strtol(hdr.ar_size, NULL, 0);
/* align to even */
size = (size + 1) & ~1;
if (alacarte) {
/* coff symbol table : we handle it */
if (!strcmp(hdr.ar_name, "/"))
Expand All @@ -3465,7 +3465,8 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
if (tcc_load_object_file(s1, fd, file_offset) < 0)
return -1;
}
file_offset += size;
/* align to even */
file_offset = (file_offset + size + 1) & ~1;
}
}

Expand Down
9 changes: 7 additions & 2 deletions tcctools.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
ElfW(Shdr) *shdr;
ElfW(Sym) *sym;
int i, fsize, i_lib, i_obj;
char *buf, *shstr, *symtab = NULL, *strtab = NULL;
char *buf, *shstr, *symtab, *strtab;
int symtabsize = 0;//, strtabsize = 0;
char *anames = NULL;
int *afpos = NULL;
Expand Down Expand Up @@ -174,6 +174,8 @@ ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
/* ignore date/uid/gid/mode */
}
}
if (fsize & 1)
fgetc(fh);
tcc_free(buf);
}
ret = 0;
Expand Down Expand Up @@ -232,6 +234,7 @@ ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)

shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
shstr = (char *)(buf + shdr->sh_offset);
symtab = strtab = NULL;
for (i = 0; i < ehdr->e_shnum; i++)
{
shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize);
Expand All @@ -252,7 +255,7 @@ ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
}
}

if (symtab && symtabsize)
if (symtab && strtab)
{
int nsym = symtabsize / sizeof(ElfW(Sym));
//printf("symtab: info size shndx name\n");
Expand Down Expand Up @@ -298,6 +301,8 @@ ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
tcc_free(buf);
i_obj++;
fpos += (fsize + sizeof(arhdro));
if (fpos & 1)
fputc(0, fo), ++fpos;
}
hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int);
fpos = 0;
Expand Down

0 comments on commit 9fb89c2

Please sign in to comment.