WIP replace ELF part with COFF

This commit is contained in:
d0p1 🏳️‍⚧️ 2025-02-21 15:10:26 +01:00
parent c5d1e40ebe
commit 5a54c79520
22 changed files with 1799 additions and 1400 deletions

View file

@ -28,10 +28,7 @@
Author (name) I agree (YES/NO) Files/Features (optional)
------------------------------------------------------------------------------
Adam Sampson YES makefiles
Daniel Glöckner NO arm-gen.c
Daniel Glöckner YES not arm-gen.c
Danny Milosavljevic YES arm-asm.c riscv64-asm.c
Edmund Grimley Evans YES arm64
Daniel Glöckner YES
Fabrice Bellard YES original author
Frédéric Féret YES x86 64/16 bit asm
grischka YES tccpe.c
@ -41,13 +38,11 @@
Kirill Smelkov YES
mingodad YES
Pip Cet YES
Shinichiro Hamaji YES x86_64-gen.c
Steffen Nurpmeso YES
Vincent Lefèvre YES
Thomas Preud'homme YES arm-gen.c
Timo VJ Lähde (Timppa) ? tiny_libmaker.c
TK ? tcccoff.c c67-gen.c
Tyge Løvset YES tgmath.h, Windows tcc_libm.h math.h
TK ? tcccoff.c
Tyge Løvset YES tgmath.h
Urs Janssen YES
waddlesplash YES
Christian Jullien YES Windows Cygwin build and tests

View file

@ -1,7 +1,7 @@
noinst_LIBRARIES = libtcc.a
libtcc_a_SOURCES = libtcc.c option.c path.c io.c memory.c \
cc/tccpp.c cc/tccgen.c \
cc/tccasm.c tccelf.c \
cc/tccasm.c \
cc/i386/gen.c cc/i386/link.c \
cc/i386/asm.c tcccoff.c
cc/i386/asm.c object/coff.c object/archive.c object.c
libtcc_a_CPPFLAGS = -I$(top_srcdir) -I$(srcdir) -I$(srcdir)/include

View file

@ -1,6 +1,7 @@
#ifndef TCC_CC_H
# define TCC_CC_H
#include "tcc/state.h"
# include <tcc.h>
/* ------------ tccpp.c ------------ */
@ -122,14 +123,12 @@ int ieee_finite(double d);
int exact_log2p1(int i);
void test_lvalue(void);
ElfSym *elfsym(Sym *);
COFFSym *coffsym(Sym *);
void update_storage(Sym *sym);
void put_extern_sym2(Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore);
void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
#if PTR_SIZE == 4
void greloc(Section *s, Sym *sym, unsigned long offset, int type);
#endif
void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend);
void put_extern_sym(Sym *sym, TCCSection *section, addr_t value, unsigned long size);
void greloc(TCCSection *s, Sym *sym, unsigned long offset, int type);
void greloca(TCCSection *s, Sym *sym, unsigned long offset, int type, addr_t addend);
void sym_free(Sym *sym);
Sym *sym_push(int v, CType *type, int r, int c);
@ -156,9 +155,7 @@ void vrott(int n);
void vrotb(int n);
void vrev(int n);
void vpop(void);
#if PTR_SIZE == 4
void lexpand(void);
#endif
void save_reg(int r);
void save_reg_upstack(int r, int n);
int get_reg(int rc);
@ -181,13 +178,12 @@ int expr_const(void);
/* ------------ xxx-link.c ------------ */
#if !defined ELF_OBJ_ONLY
int code_reloc (int reloc_type);
#define NEED_RELOC_TYPE
#endif
void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
/*void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
*/
/* ------------ xxx-gen.c ------------ */
extern const char * const target_machine_defs;
@ -269,7 +265,12 @@ void subst_asm_operand(CString *add_str, SValue *sv, int modifier);
void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg);
void asm_clobber(uint8_t *clobber_regs, const char *str);
#define ST_ASM_SET 0x04
/** XXX: fixme */
/* Symbol visibility specification encoded in the st_other field. */
#define STV_DEFAULT 0 /* Default symbol visibility rules */
#define STV_INTERNAL 1 /* Processor specific hidden class */
#define STV_HIDDEN 2 /* Sym unavailable in other modules */
#define STV_PROTECTED 3 /* Not preemptible, not exported */
#endif /* !TCC_CC_H */

View file

@ -19,6 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "tcc/object/coff.h"
#ifndef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
@ -27,7 +28,7 @@
#include "tcc.h"
#define USING_GLOBALS
#include "cc/cc.h"
#include "cC/token.h"
#include "cc/token.h"
#define MAX_OPERANDS 3
@ -403,15 +404,20 @@ void gen_expr32(ExprValue *pe)
static void gen_disp32(ExprValue *pe)
{
Sym *sym = pe->sym;
ElfSym *esym = elfsym(sym);
if (esym && esym->st_shndx == tcc_state->cur_text_section->sh_num) {
COFFSym *csym = coffsym(sym);
if (csym && csym->scnum == tcc_state->cur_text_section->secnum)
{
/* same section: we can output an absolute value. Note
that the TCC compiler behaves differently here because
it always outputs a relocation to ease (future) code
elimination in the linker */
gen_le32(pe->v + esym->st_value - ind - 4);
} else {
if (sym && sym->type.t == VT_VOID) {
gen_le32(pe->v + csym->value - ind - 4);
}
else
{
if (sym && sym->type.t == VT_VOID)
{
sym->type.t = VT_FUNC;
sym->type.ref = NULL;
}
@ -809,32 +815,44 @@ again:
}
if (pa->instr_type & OPC_B)
v += s >= 1;
if (nb_ops == 1 && pa->op_type[0] == OPT_DISP8) {
ElfSym *esym;
if (nb_ops == 1 && pa->op_type[0] == OPT_DISP8)
{
COFFSym *csym;
int jmp_disp;
/* see if we can really generate the jump with a byte offset */
esym = elfsym(ops[0].e.sym);
if (!esym || esym->st_shndx != tcc_state->cur_text_section->sh_num)
csym = coffsym(ops[0].e.sym);
if (!csym || csym->scnum != tcc_state->cur_text_section->secnum)
{
goto no_short_jump;
jmp_disp = ops[0].e.v + esym->st_value - ind - 2 - (v >= 0xff);
if (jmp_disp == (int8_t)jmp_disp) {
}
jmp_disp = ops[0].e.v + csym->value - ind - 2 - (v >= 0xff);
if (jmp_disp == (int8_t)jmp_disp)
{
/* OK to generate jump */
ops[0].e.sym = 0;
ops[0].e.v = jmp_disp;
op_type[0] = OP_IM8S;
} else {
no_short_jump:
}
else
{
no_short_jump:
/* long jump will be allowed. need to modify the
opcode slightly */
if (v == 0xeb) /* jmp */
{
v = 0xe9;
}
else if (v == 0x70) /* jcc */
{
v += 0x0f10;
}
else
{
tcc_error("invalid displacement");
}
}
}
if (OPCT_IS(pa->instr_type, OPC_TEST))
v += test_bits[opcode - pa->sym];
else if (OPCT_IS(pa->instr_type, OPC_0F01))

View file

@ -18,6 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "tcc/object/coff.h"
#define USING_GLOBALS
#include <tcc.h>
#include "cc/token.h"
@ -44,14 +45,21 @@ static unsigned long func_sub_sp_offset;
static int func_ret_sub;
/* XXX: make it faster ? */
void g(int c)
void
g(int c)
{
int ind1;
if (nocode_wanted)
{
return;
}
ind1 = ind + 1;
if (ind1 > tcc_state->cur_text_section->data_allocated)
section_realloc(tcc_state->cur_text_section, ind1);
{
coff_section_realloc(tcc_state->cur_text_section, ind1);
}
tcc_state->cur_text_section->data[ind] = c;
ind = ind1;
}
@ -111,17 +119,22 @@ void gen_fill_nops(int bytes)
#define gjmp2(instr,lbl) oad(instr,lbl)
/* output constant with relocation if 'r & VT_SYM' is true */
void gen_addr32(int r, Sym *sym, int c)
void
gen_addr32(int r, Sym *sym, int c)
{
if (r & VT_SYM)
greloc(tcc_state->cur_text_section, sym, ind, R_386_32);
{
greloc(tcc_state->cur_text_section, sym, ind, COFF_R_DIR32);
}
gen_le32(c);
}
void gen_addrpc32(int r, Sym *sym, int c)
{
if (r & VT_SYM)
greloc(tcc_state->cur_text_section, sym, ind, R_386_PC32);
{
greloc(tcc_state->cur_text_section, sym, ind, COFF_R_PCRLONG);
}
gen_le32(c - 4);
}
@ -272,14 +285,18 @@ static void gadd_sp(int val)
}
/* 'is_jmp' is '1' if it is a jump */
static void gcall_or_jmp(int is_jmp)
static void
gcall_or_jmp(int is_jmp)
{
int r;
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM))
{
/* constant and relocation case */
greloc(tcc_state->cur_text_section, vtop->sym, ind + 1, R_386_PC32);
greloc(tcc_state->cur_text_section, vtop->sym, ind + 1, COFF_R_PCRLONG);
oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
} else {
}
else
{
/* otherwise, indirect call */
r = gv(RC_INT);
o(0xff); /* call/jmp *r */
@ -938,19 +955,6 @@ void gen_cvt_csti(int t)
);
}
/* increment tcov counter */
void gen_increment_tcov (SValue *sv)
{
o(0x0583); /* addl $1, xxx */
greloc(tcc_state->cur_text_section, sv->sym, ind, R_386_32);
gen_le32(0);
o(1);
o(0x1583); /* addcl $0, xxx */
greloc(tcc_state->cur_text_section, sv->sym, ind, R_386_32);
gen_le32(4);
g(0);
}
/* computed goto support */
void ggoto(void)
{

View file

@ -1,33 +1,7 @@
#include <tcc.h>
#include "cc/cc.h"
#ifdef NEED_RELOC_TYPE
/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
relocations, returns -1. */
int code_reloc (int reloc_type)
{
switch (reloc_type) {
case R_386_RELATIVE:
case R_386_16:
case R_386_32:
case R_386_GLOB_DAT:
case R_386_COPY:
case R_386_TLS_GD:
case R_386_TLS_LDM:
case R_386_TLS_LDO_32:
case R_386_TLS_LE:
return 0;
case R_386_PC16:
case R_386_PC32:
case R_386_JMP_SLOT:
return 1;
}
return -1;
}
#endif
#if 0
void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
{
int sym_index;
@ -142,3 +116,4 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
return;
}
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "tcc/object/coff.h"
#include "tcc/state.h"
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
@ -128,7 +130,7 @@ static struct scope {
} *cur_scope, *loop_scope, *root_scope;
typedef struct {
Section *sec;
TCCSection *sec;
int local_offset;
Sym *flex_array_ref;
} init_params;
@ -406,36 +408,61 @@ void tccgen_finish(TCCState *s1)
}
/* ------------------------------------------------------------------------- */
ElfSym *elfsym(Sym *s)
COFFSym *
coffsym(Sym *s)
{
if (!s || !s->c)
return NULL;
return &((ElfSym *)tcc_state->symtab_section->data)[s->c];
{
return (NULL);
}
return (&((COFFSym *)tcc_state->symtab->syms)[s->c]);
}
/* apply storage attributes to Elf symbol */
void update_storage(Sym *sym)
/* apply storage attributes to COFF symbol */
void
update_storage(Sym *sym)
{
ElfSym *esym;
int sym_bind, old_sym_bind;
COFFSym *csym;
int sym_bind;
esym = elfsym(sym);
if (!esym)
return;
csym = coffsym(sym);
if (!csym) return;
if (sym->a.visibility)
esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
| sym->a.visibility;
{
/** XXX: visibility */
if (sym->a.visibility == STV_HIDDEN)
{
csym->sclass = COFF_C_HIDDEN;
}
else if (sym->a.visibility == STV_DEFAULT)
{
csym->sclass = COFF_C_EXT;
}
/*esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
| sym->a.visibility;*/
}
/** XXX: sym type */
if (sym->type.t & (VT_STATIC | VT_INLINE))
sym_bind = STB_LOCAL;
{
sym_bind = COFF_C_STAT;
/*sym_bind = STB_LOCAL;*/
}
else if (sym->a.weak)
sym_bind = STB_WEAK;
{
sym_bind = COFF_C_ALIAS;
/* sym_bind = STB_WEAK;*/
}
else
sym_bind = STB_GLOBAL;
old_sym_bind = ELFW(ST_BIND)(esym->st_info);
if (sym_bind != old_sym_bind) {
esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info));
{
/*sym_bind = STB_GLOBAL;*/
sym_bind = COFF_C_EXT;
}
if (csym->sclass != sym_bind)
{
csym->sclass = sym_bind;
}
}
@ -443,80 +470,91 @@ void update_storage(Sym *sym)
/* update sym->c so that it points to an external symbol in section
'section' with value 'value' */
void put_extern_sym2(Sym *sym, int sh_num,
void
put_extern_sym2(Sym *sym, int sh_num,
addr_t value, unsigned long size,
int can_add_underscore)
{
int sym_type, sym_bind, info, other, t;
ElfSym *esym;
COFFSym *csym;
const char *name;
char buf1[256];
if (!sym->c) {
if (!sym->c)
{
name = get_tok_str(sym->v, NULL);
t = sym->type.t;
if ((t & VT_BTYPE) == VT_FUNC) {
sym_type = STT_FUNC;
} else if ((t & VT_BTYPE) == VT_VOID) {
sym_type = STT_NOTYPE;
if ((t & (VT_BTYPE|VT_ASM_FUNC)) == VT_ASM_FUNC)
sym_type = STT_FUNC;
} else {
sym_type = STT_OBJECT;
if ((t & VT_BTYPE) == VT_FUNC)
{
/* sym_type = STT_FUNC;*/
sym_type = COFF_DT_FCN;
}
else if ((t & VT_BTYPE) == VT_VOID)
{
sym_type = COFF_DT_NON; /* notype*/
if ((t & (VT_BTYPE|VT_ASM_FUNC)) == VT_ASM_FUNC)
{
/*sym_type = STT_FUNC;*/
sym_type = COFF_DT_FCN;
}
}
if (t & (VT_STATIC | VT_INLINE))
sym_bind = STB_LOCAL;
else
sym_bind = STB_GLOBAL;
{
/** XXX: sym_type = STT_OBJECT; */
}
if (t & (VT_STATIC | VT_INLINE))
{
sym_bind = COFF_C_STAT;
}
else
{
sym_bind = COFF_C_EXT;
}
other = 0;
#ifdef TCC_TARGET_PE
if (sym_type == STT_FUNC && sym->type.ref) {
Sym *ref = sym->type.ref;
if (ref->a.nodecorate) {
can_add_underscore = 0;
}
if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) {
sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE);
name = buf1;
other |= ST_PE_STDCALL;
can_add_underscore = 0;
}
}
#endif
if (sym->asm_label) {
if (sym->asm_label)
{
name = get_tok_str(sym->asm_label, NULL);
can_add_underscore = 0;
}
if (tcc_state->leading_underscore && can_add_underscore) {
if (tcc_state->leading_underscore && can_add_underscore)
{
buf1[0] = '_';
pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
name = buf1;
}
info = ELFW(ST_INFO)(sym_bind, sym_type);
sym->c = put_elf_sym(tcc_state->symtab_section, value, size, info, other, sh_num, name);
sym->c = coff_add_sym(tcc_state, value, name, size, sh_num, sym_type, sym_bind);
} else {
esym = elfsym(sym);
esym->st_value = value;
esym->st_size = size;
esym->st_shndx = sh_num;
/** XXX: info = ELFW(ST_INFO)(sym_bind, sym_type);
sym->c = put_elf_sym(tcc_state->symtab_section, value, size, info, other, sh_num, name);*/
}
else
{
csym = coffsym(sym);
csym->value = value;
csym->scnum = sh_num;
/** XXX: esym->st_size = size; */
}
update_storage(sym);
}
void put_extern_sym(Sym *sym, Section *s, addr_t value, unsigned long size)
void
put_extern_sym(Sym *sym, TCCSection *s, addr_t value, unsigned long size)
{
if (nocode_wanted && (NODATA_WANTED || (s && s == tcc_state->cur_text_section)))
{
return;
put_extern_sym2(sym, s ? s->sh_num : SHN_UNDEF, value, size, 1);
}
put_extern_sym2(sym, s ? s->secnum : COFF_N_UNDEF, value, size, 1);
}
/* add a new relocation entry to symbol 'sym' in section 's' */
void greloca(Section *s, Sym *sym, unsigned long offset, int type,
void
greloca(TCCSection *s, Sym *sym, unsigned long offset, int type,
addr_t addend)
{
int c = 0;
@ -531,15 +569,14 @@ void greloca(Section *s, Sym *sym, unsigned long offset, int type,
}
/* now we can add ELF relocation info */
put_elf_reloca(tcc_state->symtab_section, s, offset, type, c, addend);
coff_add_reloca(tcc_state, s, offset, type, c, addend);
}
#if PTR_SIZE == 4
void greloc(Section *s, Sym *sym, unsigned long offset, int type)
void
greloc(TCCSection *s, Sym *sym, unsigned long offset, int type)
{
greloca(s, sym, offset, type, 0);
}
#endif
/* ------------------------------------------------------------------------- */
/* symbol allocator */
@ -1040,7 +1077,8 @@ void vpushsym(CType *type, Sym *sym)
}
/* Return a static symbol pointing to a section */
Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
Sym *
get_sym_ref(CType *type, TCCSection *sec, unsigned long offset, unsigned long size)
{
int v;
Sym *sym;
@ -1053,7 +1091,8 @@ Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long
}
/* push a reference to a section offset by adding a dummy symbol */
static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
static void
vpush_ref(CType *type, TCCSection *sec, unsigned long offset, unsigned long size)
{
vpushsym(type, get_sym_ref(type, sec, offset, size));
}
@ -1614,7 +1653,7 @@ int gv(int rc)
size = type_size(&vtop->type, &align);
if (NODATA_WANTED)
size = 0, align = 1;
offset = section_add(p.sec, size, align);
offset = coff_section_add(p.sec, size, align);
vpush_ref(&vtop->type, p.sec, offset, size);
vswap();
init_putv(&p, &vtop->type, offset);
@ -3547,7 +3586,7 @@ redo:
case TOK_SECTION2:
skip('(');
astr = parse_mult_str("section name")->data;
ad->section = find_section(tcc_state, astr);
ad->section = coff_find_section(tcc_state, astr);
skip(')');
break;
case TOK_ALIAS1:
@ -6974,8 +7013,10 @@ static void init_putz(init_params *p, unsigned long c, int size)
/* delete relocations for specified range c ... c + size. Unfortunatly
in very special cases, relocations may occur unordered */
static void decl_design_delrels(Section *sec, int c, int size)
static void
decl_design_delrels(TCCSection *sec, int c, int size)
{
/** XXX: TODO
ElfW_Rel *rel, *rel2, *rel_end;
if (!sec || !sec->reloc)
return;
@ -6990,7 +7031,7 @@ static void decl_design_delrels(Section *sec, int c, int size)
++rel2;
}
++rel;
}
}*/
}
static void decl_design_flex(init_params *p, Sym *ref, int index)
@ -7135,13 +7176,14 @@ static int decl_designator(init_params *p, CType *type, unsigned long c,
}
/* store a value or an expression directly in global data or in local array */
static void init_putv(init_params *p, CType *type, unsigned long c)
static void
init_putv(init_params *p, CType *type, unsigned long c)
{
int bt;
void *ptr;
CType dtype;
int size, align;
Section *sec = p->sec;
TCCSection *sec = p->sec;
uint64_t val;
dtype = *type;
@ -7149,10 +7191,13 @@ static void init_putv(init_params *p, CType *type, unsigned long c)
size = type_size(type, &align);
if (type->t & VT_BITFIELD)
{
size = (BIT_POS(type->t) + BIT_SIZE(type->t) + 7) / 8;
}
init_assert(p, c + size);
if (sec) {
if (sec)
{
/* XXX: not portable */
/* XXX: generate error if incorrect relocation */
gen_assign_cast(&dtype);
@ -7162,11 +7207,13 @@ static void init_putv(init_params *p, CType *type, unsigned long c)
&& bt != VT_PTR
&& (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT)
|| (type->t & VT_BITFIELD))
&& !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM)
)
&& !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM))
{
tcc_error("initializer element is not computable at load time");
}
if (NODATA_WANTED) {
if (NODATA_WANTED)
{
vtop--;
return;
}
@ -7175,8 +7222,8 @@ static void init_putv(init_params *p, CType *type, unsigned long c)
val = vtop->c.i;
/* XXX: make code faster ? */
if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
vtop->sym->v >= SYM_FIRST_ANOM &&
if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST)
&& vtop->sym->v >= SYM_FIRST_ANOM
/* XXX This rejects compound literals like
'(void *){ptr}'. The problem is that '&sym' is
represented the same way, which would be ruled out
@ -7187,40 +7234,46 @@ static void init_putv(init_params *p, CType *type, unsigned long c)
between '(void *){x}' and '&(void *){x}'. Ignore
pointer typed entities here. Hopefully no real code
will ever use compound literals with scalar type. */
(vtop->type.t & VT_BTYPE) != VT_PTR) {
&& (vtop->type.t & VT_BTYPE) != VT_PTR)
{
/* These come from compound literals, memcpy stuff over. */
Section *ssec;
ElfSym *esym;
ElfW_Rel *rel;
esym = elfsym(vtop->sym);
ssec = tcc_state->sections[esym->st_shndx];
memmove (ptr, ssec->data + esym->st_value + (int)vtop->c.i, size);
if (ssec->reloc) {
TCCSection *ssec;
COFFSym *csym;
COFFReloc *rel;
csym = coffsym(vtop->sym);
ssec = tcc_state->sections[csym->scnum];
memmove(ptr, ssec->data + csym->value + (int)vtop->c.i, size);
if (ssec->reloc)
{
/* We need to copy over all memory contents, and that
includes relocations. Use the fact that relocs are
created it order, so look from the end of relocs
until we hit one before the copied region. */
unsigned long relofs = ssec->reloc->data_offset;
while (relofs >= sizeof(*rel)) {
relofs -= sizeof(*rel);
rel = (ElfW_Rel*)(ssec->reloc->data + relofs);
if (rel->r_offset >= esym->st_value + size)
size_t reloc_idx = ssec->nreloc;
while (reloc_idx > 0)
{
reloc_idx--;
rel = &ssec->reloc[reloc_idx];
if (rel->vaddr >= csym->value + size)
{
continue;
if (rel->r_offset < esym->st_value)
}
if (rel->vaddr < csym->value)
{
break;
put_elf_reloca(tcc_state->symtab_section, sec,
c + rel->r_offset - esym->st_value,
ELFW(R_TYPE)(rel->r_info),
ELFW(R_SYM)(rel->r_info),
#if PTR_SIZE == 8
rel->r_addend
#else
0
#endif
);
}
coff_add_reloca(tcc_state, sec,
c + rel->vaddr - csym->value,
rel->type, rel->symndx, 0);
}
}
} else {
}
else
{
if (type->t & VT_BITFIELD) {
int bit_pos, bit_size, bits, n;
unsigned char *p, v, m;
@ -7285,29 +7338,15 @@ static void init_putv(init_params *p, CType *type, unsigned long c)
#endif
break;
#if PTR_SIZE == 8
/* intptr_t may need a reloc too, see tcctest.c:relocation_test() */
case VT_LLONG:
case VT_PTR:
if (vtop->r & VT_SYM)
greloca(sec, vtop->sym, c, R_DATA_PTR, val);
else
write64le(ptr, val);
break;
case VT_INT:
write32le(ptr, val);
break;
#else
case VT_LLONG:
write64le(ptr, val);
break;
case VT_PTR:
case VT_INT:
if (vtop->r & VT_SYM)
greloc(sec, vtop->sym, c, R_DATA_PTR);
greloc(sec, vtop->sym, c, COFF_R_DIR32);
write32le(ptr, val);
break;
#endif
default:
//tcc_internal_error("unexpected type");
break;
@ -7547,13 +7586,14 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f
are parsed. If 'v' is zero, then a reference to the new object
is put in the value stack. If 'has_init' is 2, a special parsing
is done to handle string constants. */
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
static void
decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
int has_init, int v, int global)
{
int size, align, addr;
TokenString *init_str = NULL;
Section *sec;
TCCSection *sec;
Sym *flexible_array;
Sym *sym;
int saved_nocode_wanted = nocode_wanted;
@ -7687,7 +7727,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
}
patch_storage(sym, ad, type);
/* we accept several definitions of the same global variable. */
if (!has_init && sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)
if (!has_init && sym->c && coffsym(sym)->scnum != COFF_N_UNDEF)
goto no_alloc;
}
}
@ -7706,7 +7746,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
sec = tcc_state->bss_section;
}
}
addr = section_add(sec, size, align);
addr = coff_section_add(sec, size, align);
if (v) {
if (!sym) {
@ -7814,7 +7854,7 @@ static void gen_function(Sym *sym)
ind = tcc_state->cur_text_section->data_offset;
if (sym->a.aligned) {
size_t newoff = section_add(tcc_state->cur_text_section, 0,
size_t newoff = coff_section_add(tcc_state->cur_text_section, 0,
1 << (sym->a.aligned - 1));
gen_fill_nops(newoff - ind);
}
@ -7827,11 +7867,12 @@ static void gen_function(Sym *sym)
/* NOTE: we patch the symbol size later */
put_extern_sym(sym, tcc_state->cur_text_section, ind, 0);
/** XXX: ???
if (sym->type.ref->f.func_ctor)
add_array (tcc_state, ".init_array", sym->c);
if (sym->type.ref->f.func_dtor)
add_array (tcc_state, ".fini_array", sym->c);
*/
/* push a dummy symbol to enable local sym storage */
sym_push2(&local_stack, SYM_FIELD, 0, 0);
@ -7851,8 +7892,9 @@ static void gen_function(Sym *sym)
gfunc_epilog();
/** XXX: ??? */
/* patch symbol size */
elfsym(sym)->st_size = ind - func_ind;
/*coffsym(sym)->st_size = ind - func_ind;*/
tcc_state->cur_text_section->data_offset = ind;
local_scope = 0;
@ -7944,7 +7986,7 @@ static int decl(int l)
CType type, btype;
Sym *sym;
AttributeDef ad, adbase;
ElfSym *esym;
COFFSym *csym;
while (1) {
@ -8076,8 +8118,8 @@ static int decl(int l)
tcc_state->cur_text_section = ad.section;
if (!tcc_state->cur_text_section)
tcc_state->cur_text_section = tcc_state->text_section;
else if (tcc_state->cur_text_section->sh_num > tcc_state->bss_section->sh_num)
tcc_state->cur_text_section->sh_flags = tcc_state->text_section->sh_flags;
else if (tcc_state->cur_text_section->secnum > tcc_state->bss_section->secnum)
tcc_state->cur_text_section->flags = tcc_state->text_section->flags;
gen_function(sym);
}
break;
@ -8160,11 +8202,13 @@ static int decl(int l)
We only support the case where the base is already
defined, otherwise we would need deferring to emit
the aliases until the end of the compile unit. */
esym = elfsym(sym_find(ad.alias_target));
if (!esym)
csym = coffsym(sym_find(ad.alias_target));
if (!csym)
{
tcc_error("unsupported forward __alias__ attribute");
put_extern_sym2(sym_find(v), esym->st_shndx,
esym->st_value, esym->st_size, 1);
}
put_extern_sym2(sym_find(v), csym->scnum,
csym->value, /** XXX: esym->st_size */0, 1);
}
}
if (tok != ',') {

View file

@ -118,7 +118,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
/* -------------------------------------------- */
#include <libtcc.h>
#include <tcc/elf.h>
/*#include <tcc/elf.h>*/
#include <tcc/object/coff.h>
#include <tcc/utils/cstring.h>
@ -131,7 +131,6 @@ extern long double strtold (const char *__nptr, char **__endptr);
/* -------------------------------------------- */
/* include the target specific definitions */
# include "tcc/i386/gen.h"
# include "tcc/i386/link.h"
# define ELFCLASSW ELFCLASS32
# define ElfW(type) Elf##32##_##type
@ -270,6 +269,7 @@ typedef struct Sym {
struct Sym *prev_tok; /* previous symbol for this token */
} Sym;
#if 0
/* section definition */
typedef struct Section {
unsigned long data_offset; /* current data offset */
@ -304,6 +304,8 @@ typedef struct Section {
char old_name[1]; /* section name */
} Section;
#endif
/* -------------------------------------------------- */
#define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
@ -344,6 +346,8 @@ typedef struct Section {
#include <tcc/io.h>
#define WARN_ON 1
/* used to record tokens */
typedef struct TokenString {
int *str;
@ -362,7 +366,7 @@ typedef struct TokenString {
typedef struct AttributeDef {
struct SymAttr a;
struct FuncAttr f;
struct Section *section;
struct TCCSection *section;
Sym *cleanup_func;
int alias_target; /* token */
int asm_label; /* associated asm label */
@ -409,6 +413,7 @@ typedef struct ASMOperand {
int is_label; /* for asm goto */
} ASMOperand;
#if 0
struct TCCState {
unsigned char verbose; /* if true, display some information during compilation */
unsigned char nostdinc; /* if true, no standard headers are added */
@ -562,6 +567,9 @@ struct TCCState {
char **argv;
CString linker_arg; /* collect -Wl options */
};
#else
# include <tcc/state.h>
#endif
struct filespec {
char type;
@ -686,11 +694,7 @@ int tcc_add_file_internal(TCCState *s1, const char *filename, int flags);
#define AFF_TYPE_ASMPP 4
#define AFF_TYPE_LIB 8
#define AFF_TYPE_MASK (15 | AFF_TYPE_BIN)
/* values from tcc_object_type(...) */
#define AFF_BINTYPE_REL 1
#define AFF_BINTYPE_DYN 2
#define AFF_BINTYPE_AR 3
#define AFF_BINTYPE_COFF 4
/* return value of tcc_add_file_internal(): 0, -1, or FILE_NOT_FOUND */
#define FILE_NOT_FOUND -2
@ -707,62 +711,36 @@ char *tcc_load_text(int fd);
/* for #pragma once */
int normalized_PATHCMP(const char *f1, const char *f2);
/* ------------ tccelf.c ------------ */
/* ------------- coff.c ------------- */
void coff_delete(TCCState *s1);
void coff_new(TCCState *s1);
void coff_section_realloc(TCCSection *sec, size_t new_size);
TCCSection *coff_find_section(TCCState *s1, const char *name);
void *coff_section_ptr_add(TCCSection *sec, size_t size);
int coff_add_sym(TCCState *s1, uint32_t value, const char *name, size_t size,
int16_t scnum, uint16_t type, int8_t sclass);
void coff_add_reloca(TCCState *s1, TCCSection *s, uint32_t offset,
int type, int symbol, uint32_t addend);
size_t coff_section_add(TCCSection *sec, size_t size, int align);
void coff_begin_file(TCCState *s1);
void coff_end_file(TCCState *s1);
int coff_load_file(TCCState *s1, int fd, unsigned long file_offset);
void coff_add_crtbegin(TCCState *s1);
void coff_add_crtend(TCCState *s1);
/* ------------- archive.c ---------- */
int archive_load(TCCState *s1, int fd, int alacarte);
#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */
#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
#define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */
#define ARMAG "!<arch>\n" /* For COFF and a.out archives */
void tccelf_new(TCCState *s);
void tccelf_delete(TCCState *s);
void tccelf_begin_file(TCCState *s1);
void tccelf_end_file(TCCState *s1);
Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
void section_realloc(Section *sec, unsigned long new_size);
size_t section_add(Section *sec, addr_t size, int align);
void *section_ptr_add(Section *sec, addr_t size);
Section *find_section(TCCState *s1, const char *name);
void free_section(Section *s);
Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags);
void init_symtab(Section *s);
int put_elf_str(Section *s, const char *sym);
int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
int set_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
int find_elf_sym(Section *s, const char *name);
void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend);
void resolve_common_syms(TCCState *s1);
void relocate_syms(TCCState *s1, Section *symtab, int do_resolve);
void relocate_sections(TCCState *s1);
ssize_t full_read(int fd, void *buf, size_t count);
void *load_data(int fd, unsigned long file_offset, unsigned long size);
int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
int tcc_load_archive(TCCState *s1, int fd, int alacarte);
void add_array(TCCState *s1, const char *sec, int c);
addr_t get_sym_addr(TCCState *s, const char *name, int err, int forc);
int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs);
/* Browse each elem of type <type> in section <sec> starting at elem <startoff>
using variable <elem> */
#define for_each_elem(sec, startoff, elem, type) \
for (elem = (type *) sec->data + startoff; \
elem < (type *) (sec->data + sec->data_offset); elem++)
#ifndef ELF_OBJ_ONLY
void tccelf_add_crtbegin(TCCState *s1);
void tccelf_add_crtend(TCCState *s1);
#endif
#ifndef TCC_TARGET_PE
void tcc_add_runtime(TCCState *s1);
#endif
int coff_load_file(TCCState *s1, int fd, const char *fname);
/* ------------ tccdbg.c ------------ */
#define tcc_error_noabort TCC_SET_STATE(_tcc_error_noabort)

View file

@ -1,17 +0,0 @@
#ifndef TCC_I386_LINK_H
# define TCC_I386_LINK_H 1
/* relocation type for 32 bit data relocation */
# define R_DATA_32 R_386_32
# define R_DATA_PTR R_386_32
# define R_JMP_SLOT R_386_JMP_SLOT
# define R_GLOB_DAT R_386_GLOB_DAT
# define R_COPY R_386_COPY
# define R_RELATIVE R_386_RELATIVE
# define R_NUM R_386_NUM
# define ELF_START_ADDR 0x08048000
# define ELF_PAGE_SIZE 0x1000
#endif /* !TCC_I386_LINK_H */

View file

@ -26,4 +26,7 @@ typedef struct BufferedFile {
# define CH_EOB '\\' /** end of buffer or '\0' char in file */
# define CH_EOF (-1) /** end of file */
ssize_t full_read(int fd, void *buf, size_t count);
void *load_data(int fd, unsigned long file_offset, unsigned long size);
#endif /* !TCC_IO_H */

View file

@ -1,10 +1,12 @@
#ifndef TCC_OBJECT_H
# define TCC_OBJECT_H 1
# include <tcc/object/coff.h>
# define TCC_BINTYPE_NONE 0
# define TCC_BINTYPE_COFF 1
# define TCC_BINTYPE_ARCHIVE 2
int tcc_object_type(int fd, void *h);
int tcc_object_type(int fd, COFFFileHeader *h);
#endif /* !TCC_OBJECT_H */

View file

@ -107,6 +107,40 @@ typedef struct COFFSym {
# define COFF_N_UNDEF 0
# define COFF_N_ABS -1
# define COFF_C_EFCN -1 /* physical end of a function */
# define COFF_C_NULL 0
# define COFF_C_AUTO 1
# define COFF_C_EXT 2 /* external symbol */
# define COFF_C_STAT 3 /* static */
# define COFF_C_REG 4 /* register var */
# define COFF_C_EXTDEF 5 /* external definition */
# define COFF_C_LABEL 6
# define COFF_C_ULABEL 7 /* undefined label */
# define COFF_C_MOS 8 /* member of struct */
# define COFF_C_ARG 9
# define COFF_C_STRTAG 10 /* struct tag */
# define COFF_C_MOU 11 /* member of union */
# define COFF_C_UNTAG 12 /* union tag */
# define COFF_C_TPDEF 13 /* typedef */
# define COFF_C_USTATIC 14
# define COFF_C_ENTAG 15
# define COFF_C_MOE 16
# define COFF_C_REGPARM 17
# define COFF_C_FIELD 18
# define COFF_C_BLOCK 100
# define COFF_C_FCN 101
# define COFF_C_EOS 102
# define COFF_C_FILE 103
# define COFF_C_LINE 104
# define COFF_C_ALIAS 105
# define COFF_C_HIDDEN 106
# define COFF_DT_FUNC (2 << 2)
# define COFF_DT_NON (0 << 2)
# define COFF_DT_PTR (1 << 2)
# define COFF_DT_FCN (2 << 2)
# define COFF_DT_ARY (3 << 2)
/**
* @}
*/

View file

@ -15,8 +15,9 @@
# define TCC_CACHED_INCLUDES_HASH_SIZE 32
# define TCC_PACK_STACK_SIZE 8
typedef struct TCCState2 TCCState2;
typedef struct TCCState TCCState;
typedef struct COFFSym COFFSym;
typedef struct COFFReloc COFFReloc;
typedef struct CachedInclude CachedInclude;
typedef struct InlineFunc InlineFunc;
@ -27,6 +28,7 @@ typedef struct TCCStrtab {
typedef struct TCCSymtab {
size_t nsym;
size_t start;
COFFSym *syms;
TCCStrtab strtab;
} TCCSymtab;
@ -36,16 +38,21 @@ typedef struct TCCSection {
uint8_t *data;
uint32_t data_allocated;
TCCState2 *state;
TCCState *state;
char name[8]; /** section name */
int32_t flags;
int16_t secnum;
int16_t addralign;
uint16_t type;
size_t offset;
size_t nreloc;
COFFReloc *reloc;
struct TCCSection *prev;
} TCCSection;
struct TCCState2 {
struct TCCState {
uint8_t verbose; /** if 1, display some information during compilation */
uint8_t nostdinc; /** if 1, no standard headers are added */
uint8_t nostdlib; /** if 1, no standard libraries are added */
@ -84,7 +91,7 @@ struct TCCState2 {
uint8_t gnu_ext; /** use GNU C extensions */
uint8_t tcc_ext; /** use TinyCC extensions */
uint8_t dflags; /** -dX value */
uint8_t dflag; /** -dX value */
uint8_t Pflag; /** -P switch (LINE_MACRO_OUTPUT_FORMAT) */
uint8_t has_text_addr;
@ -151,7 +158,7 @@ struct TCCState2 {
/* sections */
TCCSection **sections;
int nb_sections; /* number of sections, including first dummy section */
int nb_sections; /** number of sections, including first dummy section */
/* predefined sections */
TCCSection *text_section;
@ -171,6 +178,16 @@ struct TCCState2 {
/* for warnings/errors for object files */
const char *current_filename;
/* used by main and tcc_parse_args only */
void **files; /** files seen on command line */
int nb_files; /** number thereof */
int nb_libraries; /** number of libs thereof */
char *outfile; /** output filename */
char *deps_outfile; /** option -MF */
int argc;
char **argv;
CString linker_arg; /** collect -Wl options */
};
#endif /* !TCC_STATE_H */

View file

@ -51,3 +51,39 @@ void tcc_close(void)
tok_flags = bf->prev_tok_flags;
tcc_free(bf);
}
ssize_t
full_read(int fd, void *buf, size_t count)
{
char *cbuf;
size_t rnum;
ssize_t num;
cbuf = buf;
rnum = 0;
while (1)
{
num = read(fd, cbuf, count-rnum);
if (num < 0)
{
return num;
}
if (num == 0)
{
return rnum;
}
rnum += num;
cbuf += num;
}
}
void *
load_data(int fd, unsigned long file_offset, unsigned long size)
{
void *data;
data = tcc_malloc(size);
lseek(fd, file_offset, SEEK_SET);
full_read(fd, data, size);
return data;
}

View file

@ -28,7 +28,6 @@
#include <tcc/path.h>
#include <tcc/memory.h>
#include <tcc/object.h>
#include "utils/string.h"
#include "cc/cc.h"
/********************************************************/
@ -56,13 +55,20 @@ PUB_FUNC void tcc_exit_state(TCCState *s1)
tcc_state = NULL;
}
char *tcc_load_text(int fd)
char *
tcc_load_text(int fd)
{
int len = lseek(fd, 0, SEEK_END);
char *buf = load_data(fd, 0, len + 1);
int len;
char *buf;
len = lseek(fd, 0, SEEK_END);
buf = load_data(fd, 0, len + 1); /** XXX: rename func */
if (buf)
{
buf[len] = 0;
return buf;
}
return (buf);
}
#ifdef _WIN32
@ -300,7 +306,8 @@ int tcc_open(TCCState *s1, const char *filename)
}
/* compile the file opened in 'file'. Return non zero if errors. */
static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd)
static int
tcc_compile(TCCState *s1, int filetype, const char *str, int fd)
{
/* Here we enter the code section where we use the global variables for
parsing and code generation (tccpp.c, tccgen.c, <target>-gen.c).
@ -308,18 +315,23 @@ static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd)
Alternatively we could use thread local storage for those global
variables, which may or may not have advantages */
int len;
tcc_enter_state(s1);
s1->error_set_jmp_enabled = 1;
if (setjmp(s1->error_jmp_buf) == 0) {
if (setjmp(s1->error_jmp_buf) == 0)
{
s1->nb_errors = 0;
if (fd == -1) {
int len = strlen(str);
if (fd == -1)
{
len = strlen(str);
tcc_open_bf(s1, "<string>", len);
memcpy(file->buffer, str, len);
} else {
}
else
{
tcc_open_bf(s1, str, 0);
file->fd = fd;
}
@ -327,23 +339,29 @@ static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd)
preprocess_start(s1, filetype);
tccgen_init(s1);
if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
if (s1->output_type == TCC_OUTPUT_PREPROCESS)
{
tcc_preprocess(s1);
} else {
tccelf_begin_file(s1);
if (filetype & (AFF_TYPE_ASM | AFF_TYPE_ASMPP)) {
}
else
{
coff_begin_file(s1);
if (filetype & (AFF_TYPE_ASM | AFF_TYPE_ASMPP))
{
tcc_assemble(s1, !!(filetype & AFF_TYPE_ASMPP));
} else {
}
else
{
tccgen_compile(s1);
}
tccelf_end_file(s1);
coff_end_file(s1);
}
}
tccgen_finish(s1);
preprocess_end(s1);
s1->error_set_jmp_enabled = 0;
tcc_exit_state(s1);
return s1->nb_errors != 0 ? -1 : 0;
return (s1->nb_errors != 0 ? -1 : 0);
}
/* define a preprocessor symbol. value can be NULL, sym can be "sym=val" */
@ -394,10 +412,11 @@ TCCState *tcc_new(void)
return s;
}
void tcc_delete(TCCState *s1)
void
tcc_delete(TCCState *s1)
{
/* free sections */
tccelf_delete(s1);
coff_delete(s1);
/* free library paths */
dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
@ -424,7 +443,8 @@ void tcc_delete(TCCState *s1)
#endif
}
int tcc_set_output_type(TCCState *s, int output_type)
int
tcc_set_output_type(TCCState *s, int output_type)
{
s->output_type = output_type;
@ -439,11 +459,11 @@ int tcc_set_output_type(TCCState *s, int output_type)
}
/* add sections */
tccelf_new(s);
coff_new(s);
if (output_type == TCC_OUTPUT_OBJ) {
/* always elf for objects */
s->output_format = TCC_OUTPUT_FORMAT_ELF;
s->output_format = TCC_OUTPUT_FORMAT_COFF;
return 0;
}
@ -452,7 +472,7 @@ int tcc_set_output_type(TCCState *s, int output_type)
/* paths for crt objects */
tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
if (!s->nostdlib)
tccelf_add_crtbegin(s);
coff_add_crtbegin(s);
return 0;
}
@ -470,64 +490,70 @@ int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
static int guess_filetype(const char *filename);
int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
int
tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
{
COFFFileHeader fhdr;
int obj_type;
int fd, ret = -1;
if (0 == (flags & AFF_TYPE_MASK))
{
flags |= guess_filetype(filename);
}
/* ignore binary files with -E */
if (s1->output_type == TCC_OUTPUT_PREPROCESS
&& (flags & AFF_TYPE_BIN))
return 0;
{
return (0);
}
/* open the file */
fd = _tcc_open(s1, filename);
if (fd < 0) {
if (fd < 0)
{
if (flags & AFF_PRINT_ERROR)
{
tcc_error_noabort("file '%s' not found", filename);
return FILE_NOT_FOUND;
}
return (FILE_NOT_FOUND);
}
s1->current_filename = filename;
if (flags & AFF_TYPE_BIN) {
ElfW(Ehdr) ehdr;
int obj_type;
obj_type = tcc_object_type(fd, &ehdr);
if (flags & AFF_TYPE_BIN)
{
obj_type = tcc_object_type(fd, &fhdr);
lseek(fd, 0, SEEK_SET);
switch (obj_type) {
case AFF_BINTYPE_REL:
ret = tcc_load_object_file(s1, fd, 0);
switch (obj_type)
{
case TCC_BINTYPE_COFF:
ret = coff_load_file(s1, fd, 0);
break;
case AFF_BINTYPE_AR:
ret = tcc_load_archive(s1, fd, !(flags & AFF_WHOLE_ARCHIVE));
break;
case AFF_BINTYPE_COFF:
ret = coff_load_file(s1, fd, filename);
case TCC_BINTYPE_ARCHIVE:
ret = archive_load(s1, fd, !(flags & AFF_WHOLE_ARCHIVE));
break;
default:
/* as GNU ld, consider it is an ld script if not recognized */
tcc_error_noabort("%s: unrecognized file type", filename);
break;
}
close(fd);
} else {
}
else
{
/* update target deps */
dynarray_add(&s1->target_deps, &s1->nb_target_deps, tcc_strdup(filename));
ret = tcc_compile(s1, flags, filename, fd);
}
s1->current_filename = NULL;
return ret;
return (ret);
}
static int guess_filetype(const char *filename)
static int
guess_filetype(const char *filename)
{
int filetype = 0;
if (1) {

View file

@ -1,3 +1,4 @@
#include "tcc/io.h"
#include <string.h>
#include <tcc/state.h>
#include <tcc/memory.h>
@ -6,10 +7,22 @@
#include <tcc/object/coff.h>
int
tcc_object_type(int fd, void *h)
tcc_object_type(int fd, COFFFileHeader *h)
{
size_t size;
ssize_t size;
size = full_read(fd, h, sizeof(COFFFileHeader));
if (size == sizeof(COFFFileHeader)
&& h->magic == COFF_MAGIC
&& (h->flags & COFF_F_EXEC) == 0)
{
return (TCC_BINTYPE_COFF);
}
else if (size >= 8
&& memcmp(h, ARCHIVE_MAGIC, ARCHIVE_MAGSZ) == 0)
{
return (TCC_BINTYPE_ARCHIVE);
}
return (0);
return (TCC_BINTYPE_NONE);
}

View file

@ -11,3 +11,8 @@ tcc_load_archive(TCCState *s1, int fd, int alacarte)
return (0);
}
int archive_load(TCCState *s1, int fd, int alacarte)
{
}

View file

@ -1,3 +1,4 @@
#include "tcc.h"
#include "utils/string.h"
#include <stddef.h>
#include <stdint.h>
@ -18,7 +19,7 @@ void dynarray_add(void *ptab, int *nb_ptr, void *data);
void dynarray_reset(void *pp, int *n);
static TCCSection *
coff_new_section(TCCState2 *s1, const char *name, int flags)
coff_new_section(TCCState *s1, const char *name, int flags)
{
TCCSection *sec;
@ -42,10 +43,12 @@ coff_free_section(TCCSection *s)
tcc_free(s->data);
s->data = NULL;
s->data_allocated = s->data_offset = 0;
tcc_free(s->reloc);
s->reloc = NULL;
}
void
coff_new(TCCState2 *s1)
coff_new(TCCState *s1)
{
dynarray_add(&s1->sections, &s1->nb_sections, NULL);
@ -61,7 +64,7 @@ coff_new(TCCState2 *s1)
}
void
coff_delete(TCCState2 *s1)
coff_delete(TCCState *s1)
{
int i;
@ -82,7 +85,7 @@ coff_delete(TCCState2 *s1)
}
void
coff_begin_file(TCCState2 *s1)
coff_begin_file(TCCState *s1)
{
TCCSection *sec;
int i;
@ -92,6 +95,26 @@ coff_begin_file(TCCState2 *s1)
sec = s1->sections[i];
sec->offset = sec->data_offset;
}
s1->symtab->start = s1->symtab->nsym;
}
void
coff_end_file(TCCState *s1)
{
int nb_syms;
int *tr;
int i;
COFFSym *sym;
nb_syms = s1->symtab->nsym - s1->symtab->start;
tr = tcc_mallocz(nb_syms * sizeof(int));
for (i = s1->symtab->start; i < nb_syms; i++)
{
sym = &s1->symtab->syms[i];
}
}
void
@ -145,7 +168,7 @@ coff_section_ptr_add(TCCSection *sec, size_t size)
}
static TCCSection *
coff_have_section(TCCState2 *s1, const char *name)
coff_have_section(TCCState *s1, const char *name)
{
TCCSection *sec;
int i;
@ -164,7 +187,7 @@ coff_have_section(TCCState2 *s1, const char *name)
/* return a reference to a section, and create it if it does not
exists */
TCCSection *
coff_find_section(TCCState2 *s1, const char *name)
coff_find_section(TCCState *s1, const char *name)
{
TCCSection *sec;
@ -184,7 +207,7 @@ coff_find_section(TCCState2 *s1, const char *name)
*/
int
coff_add_sym(TCCState2 *s1, uint32_t value, const char *name, size_t size,
coff_add_sym(TCCState *s1, uint32_t value, const char *name, size_t size,
int16_t scnum, uint16_t type, int8_t sclass)
{
size_t symidx;
@ -197,6 +220,7 @@ coff_add_sym(TCCState2 *s1, uint32_t value, const char *name, size_t size,
s1->symtab->syms = tcc_realloc(s1->symtab->syms, sizeof(COFFSym) * s1->symtab->nsym);
sym = &(s1->symtab->syms[symidx]);
size = strlen(name); /** XXX: fixme */
if (size > 8)
{
strtaboffset = ALIGN_UP(s1->symtab->strtab.len, 1);
@ -219,7 +243,7 @@ coff_add_sym(TCCState2 *s1, uint32_t value, const char *name, size_t size,
}
int
coff_find_sym(TCCState2 *s1, const char *name)
coff_find_sym(TCCState *s1, const char *name)
{
size_t symidx;
size_t len;
@ -258,7 +282,7 @@ coff_find_sym(TCCState2 *s1, const char *name)
}
uint32_t
coff_get_sym_addr(TCCState2 *s1, const char *name, int err, int forc)
coff_get_sym_addr(TCCState *s1, const char *name, int err, int forc)
{
COFFSym *sym;
int sym_idx;
@ -285,8 +309,34 @@ coff_get_sym_addr(TCCState2 *s1, const char *name, int err, int forc)
return (sym->value);
}
/*
* ---------------------------------------------------------------------------
* Relocs
* ---------------------------------------------------------------------------
*/
void
coff_add_reloca(TCCState *s1, TCCSection *s, uint32_t offset,
int type, int symbol, uint32_t addend)
{
char buf[256];
COFFReloc *rel;
if (s->reloc == NULL)
{
s->reloc = tcc_mallocz(sizeof(COFFReloc) * UINT16_MAX);
}
rel = &s->reloc[s->nreloc];
s->nreloc++;
rel->symndx = symbol;
rel->type = type;
rel->vaddr = offset;
}
int
tcc_output_coff(TCCState2 *s1, FILE *f)
tcc_output_coff(TCCState *s1, FILE *f)
{
COFFFileHeader coffhdr;
AOutHeader aouthdr;
@ -325,19 +375,19 @@ tcc_output_coff(TCCState2 *s1, FILE *f)
}
int
coff_output_object(TCCState2 *s, const char *filename)
coff_output_object(TCCState *s, const char *filename)
{
return (0);
}
int
coff_output_exe(TCCState2 *s, const char *filename)
coff_output_exe(TCCState *s, const char *filename)
{
return (0);
}
int
coff_load_object(TCCState2 *s, int fd, size_t file_offset)
coff_load_object(TCCState *s, int fd, size_t file_offset)
{
COFFFileHeader chdr;
@ -345,3 +395,15 @@ coff_load_object(TCCState2 *s, int fd, size_t file_offset)
return (0);
}
void
coff_add_crtbegin(TCCState *s1)
{
}
void
coff_add_crtend(TCCState *s1)
{
}

View file

@ -1,113 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#include <tcc.h>
#include <tcc/path.h>
#include <tcc/memory.h>
#include <tcc/coff.h>
static int
read_mem(int fd, unsigned offset, void *buffer, unsigned len)
{
lseek(fd, offset, SEEK_SET);
return len == read(fd, buffer, len);
}
int
coff_load_lib(TCCState *s1, int fd)
{
return (0);
}
static int
coff_merge_or_create(void)
{
return (0);
}
static int
coff_resolve_symbols(void)
{
return (0);
}
int
coff_load_obj(TCCState *s1, int fd)
{
FILHDR hdr;
SCNHDR *scns;
SYMENT *syments;
RELOC *relocs;
Section *s;
uint16_t i;
int32_t j;
int k;
char buff[9];
if (!read_mem(fd, 0, &hdr, FILHSZ))
return (tcc_error_noabort("not a coff object file"));
if (hdr.f_magic != F_MACH_I386 || hdr.f_flags & F_EXEC)
return (tcc_error_noabort("invalid coff object file"));
/* read sections */
scns = tcc_malloc(SCNHSZ * hdr.f_nscns);
if (!read_mem(fd, FILHSZ, scns, SCNHSZ * hdr.f_nscns))
{
tcc_free(scns);
return (-1);
}
for (i = 0; i < hdr.f_nscns; i++)
{
memset(buff, 0, 9);
memcpy(buff, scns[i].s_name, 8);
printf("sec: %s\n", buff);
for (k = 1; k < s1->nb_sections; k++)
{
if (strcmp(s1->sections[k]->old_name, buff) != 0)
{
continue;
}
}
}
/* load symtab */
syments = tcc_malloc(SYMESZ * hdr.f_nsyms);
read_mem(fd, hdr.f_symptr, syments, SYMESZ * hdr.f_nsyms);
for (j = 0; j < hdr.f_nsyms; j++)
{
memset(buff, 0, 9);
memcpy(buff, syments[j].n_name, 8);
printf("sym: %s\n", buff);
}
tcc_free(syments);
tcc_free(scns);
return (0);
}
int
coff_load_file(TCCState *s1, int fd, const char *fname)
{
if (strcmp(tcc_fileextension(fname), ".a") == 0)
{
return (coff_load_lib(s1, fd));
}
else
{
return (coff_load_obj(s1, fd));
}
}
int
coff_output_file(TCCState *s1, const char *filename)
{
return (0);
}

View file

@ -34,7 +34,8 @@
/* Define this to get some debug output during relocation processing. */
#undef DEBUG_RELOC
# define ELF_START_ADDR 0x08048000
# define ELF_PAGE_SIZE 0x1000
/********************************************************/
/* global variables */

View file

@ -50,7 +50,7 @@ static int ar_usage(int ret) {
}
int tcc_tool_ar(TCCState *s1, int argc, char **argv)
{
{/*
static const ArchiveFileHeader arhdr_init = {
"/ ",
"0 ",
@ -141,7 +141,7 @@ no_ar:
if (strcmp(arhdr.name,"/") && strcmp(arhdr.name,"/SYM64/")) {
if (e > p && e[-1] == '/')
e[-1] = '\0';
/* tv not implemented */
// tv not implemented
if (table || verbose)
printf("%s%s\n", extract ? "x - " : "", arhdr.name);
if (extract) {
@ -154,7 +154,7 @@ no_ar:
}
fwrite(buf, fsize, 1, fo);
fclose(fo);
/* ignore date/uid/gid/mode */
// ignore date/uid/gid/mode
}
}
if (fsize & 1)
@ -328,7 +328,9 @@ the_end:
remove(created_file);
if (fo)
fclose(fo), remove(tfile);
return ret;
return ret;*/
return (-1);
}
/* -------------------------------------------------------------- */