Further split tcc into multiple file

This commit is contained in:
d0p1 🏳️‍⚧️ 2025-02-11 20:16:44 +01:00
parent ca1e24c395
commit 9eb10536b0
14 changed files with 449 additions and 2651 deletions

View file

@ -39,4 +39,28 @@ AS_CASE([$enable_memory_debug],
[[[1-3]]], [AC_DEFINE_UNQUOTED([TCC_MEMORY_DEBUG], [$enable_memory_debug], [enable memory debug])],
[*yes*], [AC_DEFINE([TCC_MEMORY_DEBUG], [1], [enable memory debug])])
AC_ARG_ENABLE([asm_debug],
[AS_HELP_STRING([--enable-asm-debug], [enable asm debug])])
AS_IF([test "x$enable_asm_debug" = "xyes"],
[AC_DEFINE([ASM_DEBUG])])
AC_ARG_ENABLE([inc_debug],
[AS_HELP_STRING([--enable-inc-debug], [enable include file debug])])
AS_IF([test "x$enable_inc_debug" = "xyes"],
[AC_DEFINE([INC_DEBUG])])
AC_ARG_ENABLE([pp_debug],
[AS_HELP_STRING([--enable-pp-debug], [enable preprocessor debug])])
AS_IF([test "x$enable_pp_debug" = "xyes"],
[AC_DEFINE([PP_DEBUG])])
AC_ARG_ENABLE([parser_debug],
[AS_HELP_STRING([--enable-parser-debug], [enable parser debug])])
AS_IF([test "x$enable_parser_debug" = "xyes"],
[AC_DEFINE([PARSE_DEBUG])])
AC_OUTPUT

View file

@ -19,6 +19,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#define USING_GLOBALS
#include "tcc.h"
#include "token.h"
@ -398,7 +402,7 @@ static void gen_disp32(ExprValue *pe)
{
Sym *sym = pe->sym;
ElfSym *esym = elfsym(sym);
if (esym && esym->st_shndx == cur_text_section->sh_num) {
if (esym && esym->st_shndx == tcc_state->cur_text_section->sh_num) {
/* 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
@ -680,12 +684,18 @@ again:
if (s == autosize) {
if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
(ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
{
s = 2;
else if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
(ops[0].type & OP_EA))
s = NBWLX - 2;
}
else if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
(ops[0].type & OP_EA))
{
s = NBWLX - 2;
}
else
{
tcc_error("cannot infer opcode suffix");
}
}
}
@ -803,7 +813,7 @@ again:
/* see if we can really generate the jump with a byte offset */
esym = elfsym(ops[0].e.sym);
if (!esym || esym->st_shndx != cur_text_section->sh_num)
if (!esym || esym->st_shndx != tcc_state->cur_text_section->sh_num)
goto no_short_jump;
jmp_disp = ops[0].e.v + esym->st_value - ind - 2 - (v >= 0xff);
if (jmp_disp == (int8_t)jmp_disp) {
@ -899,7 +909,7 @@ again:
/* after immediate operands, adjust pc-relative address */
if (pc)
add32le(cur_text_section->data + pc - 4, pc - ind);
add32le(tcc_state->cur_text_section->data + pc - 4, pc - ind);
}
/* return the constraint priority (we allocate first the lowest

View file

@ -48,9 +48,9 @@ void g(int c)
if (nocode_wanted)
return;
ind1 = ind + 1;
if (ind1 > cur_text_section->data_allocated)
section_realloc(cur_text_section, ind1);
cur_text_section->data[ind] = c;
if (ind1 > tcc_state->cur_text_section->data_allocated)
section_realloc(tcc_state->cur_text_section, ind1);
tcc_state->cur_text_section->data[ind] = c;
ind = ind1;
}
@ -80,7 +80,7 @@ void gen_le32(int c)
void gsym_addr(int t, int a)
{
while (t) {
unsigned char *ptr = cur_text_section->data + t;
unsigned char *ptr = tcc_state->cur_text_section->data + t;
uint32_t n = read32le(ptr); /* next value */
write32le(ptr, a - t - 4);
t = n;
@ -112,14 +112,14 @@ void gen_fill_nops(int bytes)
void gen_addr32(int r, Sym *sym, int c)
{
if (r & VT_SYM)
greloc(cur_text_section, sym, ind, R_386_32);
greloc(tcc_state->cur_text_section, sym, ind, R_386_32);
gen_le32(c);
}
void gen_addrpc32(int r, Sym *sym, int c)
{
if (r & VT_SYM)
greloc(cur_text_section, sym, ind, R_386_PC32);
greloc(tcc_state->cur_text_section, sym, ind, R_386_PC32);
gen_le32(c - 4);
}
@ -275,7 +275,7 @@ static void gcall_or_jmp(int is_jmp)
int r;
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
/* constant and relocation case */
greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32);
greloc(tcc_state->cur_text_section, vtop->sym, ind + 1, R_386_PC32);
oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
} else {
/* otherwise, indirect call */
@ -593,7 +593,7 @@ int gjmp_append(int n, int t)
/* insert vtop->c jump list in t */
if (n) {
uint32_t n1 = n, n2;
while ((n2 = read32le(p = cur_text_section->data + n1)))
while ((n2 = read32le(p = tcc_state->cur_text_section->data + n1)))
n1 = n2;
write32le(p, t);
t = n;
@ -940,11 +940,11 @@ void gen_cvt_csti(int t)
void gen_increment_tcov (SValue *sv)
{
o(0x0583); /* addl $1, xxx */
greloc(cur_text_section, sv->sym, ind, R_386_32);
greloc(tcc_state->cur_text_section, sv->sym, ind, R_386_32);
gen_le32(0);
o(1);
o(0x1583); /* addcl $0, xxx */
greloc(cur_text_section, sv->sym, ind, R_386_32);
greloc(tcc_state->cur_text_section, sv->sym, ind, R_386_32);
gen_le32(4);
g(0);
}

View file

@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdarg.h>
/* gnu headers use to #define __attribute__ to empty for non-gcc compilers */
#ifdef __TINYC__
# undef __attribute__
@ -40,9 +41,6 @@
#ifndef _WIN32
# include <unistd.h>
# include <sys/time.h>
# ifndef CONFIG_TCC_STATIC
# include <dlfcn.h>
# endif
/* XXX: need to define this to use them in non ISOC99 context */
extern float strtof (const char *__nptr, char **__endptr);
extern long double strtold (const char *__nptr, char **__endptr);
@ -85,17 +83,6 @@ extern long double strtold (const char *__nptr, char **__endptr);
/* -------------------------------------------- */
/* parser debug */
/* #define PARSE_DEBUG */
/* preprocessor debug */
/* #define PP_DEBUG */
/* include file debug */
/* #define INC_DEBUG */
/* memory leak debug (only for single threaded usage) */
/* #define MEM_DEBUG 1,2,3 */
/* assembler debug */
/* #define ASM_DEBUG */
#ifdef CONFIG_TCC_PIE
# define CONFIG_TCC_PIC 1
#endif
@ -167,7 +154,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
#include <libtcc.h>
#include <tcc/elf.h>
#include <tcc/coff.h>
#include <tcc/object/coff.h>
#include <tcc/utils/cstring.h>
/* -------------------------------------------- */
@ -326,10 +313,12 @@ typedef struct Section {
TCCState *s1;
/**/
char *c_name[8];
addr_t c_addr;
int32_t c_flags;
char name[8];
addr_t addr;
int32_t flags;
int32_t size;
COFFReloc *coff_reloc;
/**/
int sh_name; /* elf section name (only used during output) */
@ -347,7 +336,7 @@ typedef struct Section {
struct Section *reloc; /* corresponding section for relocation, if any */
struct Section *hash; /* hash table for symbols */
struct Section *prev; /* previous section on section stack */
char name[1]; /* section name */
char old_name[1]; /* section name */
} Section;
/* -------------------------------------------------- */
@ -1208,13 +1197,7 @@ static inline void post_sem(TCCSem *p) {
#define POST_SEM(p)
#endif
#define text_section TCC_STATE_VAR(text_section)
#define data_section TCC_STATE_VAR(data_section)
#define rodata_section TCC_STATE_VAR(rodata_section)
#define bss_section TCC_STATE_VAR(bss_section)
#define common_section TCC_STATE_VAR(common_section)
#define cur_text_section TCC_STATE_VAR(cur_text_section)
#define bounds_section TCC_STATE_VAR(bounds_section)
#define lbounds_section TCC_STATE_VAR(lbounds_section)
#define symtab_section TCC_STATE_VAR(symtab_section)

File diff suppressed because it is too large Load diff

View file

@ -62,6 +62,47 @@ typedef struct COFFSectionHeader {
int32_t flags;
} COFFSectionHeader;
# define COFF_STYP_REG 0x000
# define COFF_STYP_DSECT 0x001
# define COFF_STYP_NOLOAD 0x002
# define COFF_STYP_GROUP 0x004
# define COFF_STYP_PAD 0x008
# define COFF_STYP_COPY 0x010
# define COFF_STYP_TEXT 0x020
# define COFF_STYP_DATA 0x040
# define COFF_STYP_BSS 0x080
# define COFF_STYP_INFO 0x200
# define COFF_STYP_OVER 0x400
# define COFF_STYP_LIB 0x800
typedef struct COFFReloc {
uint32_t vaddr;
uint32_t symndx;
uint16_t type;
} COFFReloc;
# define COFF_R_ABS 0
# define COFF_R_DIR32 06
# define COFF_R_SEG12 011
# define COFF_R_PCRLONG 024
# define COFF_SYMNMLEN 8
typedef struct COFFSym {
union {
char name[COFF_SYMNMLEN];
struct {
int32_t zeroes;
int32_t offset;
} n;
} n;
uint32_t value;
int16_t scnum;
uint16_t type;
int8_t sclass;
int8_t numaux;
} COFFSym;
/**
* @}
*/

185
libtcc/include/tcc/state.h Normal file
View file

@ -0,0 +1,185 @@
#ifndef TCC_STATE_H
# define TCC_STATE_H 1
# include <setjmp.h>
# include <stdint.h>
# include <stdio.h>
# include <tcc/io.h>
# include <tcc/utils/cstring.h>
# define TCC_WARN_ON 1 /** warning is on (-Woption) */
# define TCC_INCLUDE_STACK_SIZE 32
# define TCC_IFDEF_STACK_SIZE 64
# define TCC_CACHED_INCLUDES_HASH_SIZE 32
# define TCC_PACK_STACK_SIZE 8
typedef struct TCCState2 TCCState2;
typedef struct COFFSym COFFSym;
typedef struct CachedInclude CachedInclude;
typedef struct InlineFunc InlineFunc;
typedef struct TCCStrtab {
size_t len;
uint8_t *tab;
} TCCStrtab;
typedef struct TCCSymtab {
size_t nsym;
COFFSym *syms;
TCCStrtab strtab;
} TCCSymtab;
typedef struct TCCSection {
uint32_t data_offset;
uint8_t *data;
uint32_t data_allocated;
TCCState2 *state;
char name[8]; /** section name */
int32_t flags;
int16_t secnum;
} TCCSection;
struct TCCState2 {
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 */
uint8_t symbolic; /** if 1, resolve symbols in the current module first */
uint8_t filetype; /** file type for compilation (NONE, C, ASM) */
uint8_t optimize; /** only to #define __OPTIMIZE__ */
uint8_t option_pthread; /** -pthread option */
uint32_t cversion; /** suppported C ISO version, 199901 (default), 201112, ... */
/* C language options */
uint8_t char_is_unsigned;
uint8_t leading_underscore;
uint8_t ms_extensions; /** allow nested named struct w/o identifier behave lile unnamed */
uint8_t dollars_in_identifiers; /** allows '$' char in identifiers */
uint8_t ms_bitfields; /** if 1, emulate MS algorithm for aligning bitfields */
uint8_t reverse_funcargs; /** if 1, evaluate last function arg first */
uint8_t gnu89_inline; /** treat 'extern inline' like 'static inline' */
/* warning switches */
uint8_t warn_none;
uint8_t warn_all;
uint8_t warn_error;
uint8_t warn_write_strings;
uint8_t warn_unsupported;
uint8_t warn_implicit_function_declaration;
uint8_t warn_discarded_qualifiers;
uint8_t warn_num; /** temp var for tcc_warning_c() */
uint8_t option_r; /** option -r */
uint8_t do_bench; /** option -bench */
uint8_t just_deps; /** option -M */
uint8_t gen_deps; /** option -MD */
uint8_t include_sys_deps; /** option -MD */
uint8_t gen_phony_deps; /** option -MP */
uint8_t gnu_ext; /** use GNU C extensions */
uint8_t tcc_ext; /** use TinyCC extensions */
uint8_t dflags; /** -dX value */
uint8_t Pflag; /** -P switch (LINE_MACRO_OUTPUT_FORMAT) */
uint8_t has_text_addr;
uint32_t text_addr; /** address of text section */
unsigned section_align; /** section alignment */
int seg_size; /** 32. Can be 16 with i386 assembler (.code16) */
char *tcc_lib_path; /** CONFIG_TCCDIR or -B option */
char *entryname; /** "_start" unless set */
int output_type; /** output type, see TCC_OUTPUT_xxx */
int output_format; /** output format, see TCC_OUTPUT_FORMAT_xxx */
/* include paths */
char **include_paths;
int nb_include_paths;
char **sysinclude_paths;
int nb_sysinclude_paths;
/* library paths */
char **library_paths;
int nb_library_paths;
/* crt?.o object path */
char **crt_paths;
int nb_crt_paths;
CString cmdline_defs; /** -D / -U options */
CString cmdline_incl; /** -include options */
/** error handling */
void *error_opaque;
void (*error_func)(void *opaque, const char *msg);
int error_set_jmp_enabled;
jmp_buf error_jmp_buf;
int nb_errors;
FILE *ppfp; /** output file for preprocessing (-E) */
char **target_deps; /** for -MD/-MF: collected dependencies for this compilation */
int nb_target_deps;
/* compilation */
BufferedFile *include_stack[TCC_INCLUDE_STACK_SIZE];
BufferedFile **include_stack_ptr;
int ifdef_stack[TCC_IFDEF_STACK_SIZE];
int *ifdef_stack_ptr;
/* included files enclosed with #ifndef MACRO */
int cached_includes_hash[TCC_CACHED_INCLUDES_HASH_SIZE];
CachedInclude **cached_includes;
int nb_cached_includes;
/* #pragma pack stack */
int pack_stack[TCC_PACK_STACK_SIZE];
int *pack_stack_ptr;
char **pragma_libs;
int nb_pragma_libs;
/* inline functions are stored as token lists and compiled last only if referenced */
InlineFunc **inline_fns;
int nb_inline_fns;
/* sections */
TCCSection **sections;
int nb_sections; /* number of sections, including first dummy section */
/* predefined sections */
TCCSection *text_section;
TCCSection *data_section;
TCCSection *rodata_section;
TCCSection *bss_section;
TCCSection *cur_text_section; /** current section where function code is generated */
/* symbol data */
TCCSymtab symtab;
/* exception handling */
TCCSection *eh_frame_section;
TCCSection *eh_frame_hdr_section;
uint32_t eh_start;
/* benchmark info */
int total_idents;
int total_lines;
uint32_t total_bytes;
uint32_t total_output[4];
/* used by tcc_load_ldscript */
int fd;
int cc;
/* for warnings/errors for object files */
const char *current_filename;
};
#endif /* !TCC_STATE_H */

View file

@ -1,10 +1,80 @@
#include <tcc.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* !HAVE_CONFIG_H */
#include <tcc/state.h>
#include <tcc/memory.h>
#include <tcc/object/coff.h>
#include <tcc/state.h>
#define COFF_DEFAULT_ENTRYNAME "_start"
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)
{
TCCSection *sec;
sec = tcc_mallocz(sizeof(TCCSection));
sec->state = s1;
strncpy(sec->name, name, 8); /* truncate section name */
sec->flags = flags;
sec->secnum = s1->nb_sections;
dynarray_add(&s1->sections, &s1->nb_sections, sec);
return (sec);
}
static void
coff_free_section(TCCSection *s)
{
if (!s) return;
tcc_free(s->data);
s->data = NULL;
s->data_allocated = s->data_offset = 0;
}
static void
coff_new_symtab(TCCState2 *s1)
{
TCCSymtab *symtab;
symtab = tcc_mallocz(sizeof(TCCSymtab));
}
void
coff_new(TCCState2 *s1)
{
dynarray_add(&s1->sections, &s1->nb_sections, NULL);
s1->text_section = coff_new_section(s1, ".text", COFF_STYP_TEXT);
s1->data_section = coff_new_section(s1, ".data", COFF_STYP_DATA);
s1->bss_section = coff_new_section(s1, ".bss", COFF_STYP_BSS);
s1->rodata_section = coff_new_section(s1, ".rodata", COFF_STYP_DATA);
coff_new_symtab(s1);
}
void
coff_delete(TCCState2 *s1)
{
int i;
for (i = 1; i < s1->nb_sections; i++)
{
coff_free_section(s1->sections[i]);
}
dynarray_reset(&s1->sections, &s1->nb_sections);
}
int
tcc_output_coff(TCCState *s1, FILE *f)
tcc_output_coff(TCCState2 *s1, FILE *f)
{
COFFFileHeader coffhdr;
AOutHeader aouthdr;
@ -17,7 +87,7 @@ tcc_output_coff(TCCState *s1, FILE *f)
coffhdr.magic = COFF_MAGIC;
coffhdr.nscns = s1->nb_sections;
if (s1->output_type == TCC_OUTPUT_EXE)
if (s1->output_type == /*TCC_OUTPUT_EXE*/666)
{
coffhdr.flags |= COFF_F_RELFLG | COFF_F_EXEC | COFF_F_LSYMS;
coffhdr.nsyms = 0;
@ -31,7 +101,7 @@ tcc_output_coff(TCCState *s1, FILE *f)
{
entry_name = s1->entryname;
}
aouthdr.entry = get_sym_addr(s1, entry_name, 1, 0);
//aouthdr.entry = get_sym_addr(s1, entry_name, 1, 0);
if (s1->nb_errors)
{
@ -43,13 +113,23 @@ tcc_output_coff(TCCState *s1, FILE *f)
}
int
coff_output_object(TCCState *s, const char *filename)
coff_output_object(TCCState2 *s, const char *filename)
{
return (0);
}
int
coff_output_exe(TCCState *s, const char *filename)
coff_output_exe(TCCState2 *s, const char *filename)
{
return (0);
}
int
coff_load_object(TCCState2 *s, int fd, size_t file_offset)
{
COFFFileHeader chdr;
return (0);
}

View file

@ -17,7 +17,9 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#define USING_GLOBALS
#include "tcc.h"
#include "utils/string.h"
@ -115,7 +117,7 @@ Sym* get_asm_sym(int name, Sym *csym)
static Sym* asm_section_sym(TCCState *s1, Section *sec)
{
char buf[100]; int label; Sym *sym;
snprintf(buf, sizeof buf, "L.%s", sec->name);
snprintf(buf, sizeof buf, "L.%s", sec->old_name);
label = tok_alloc_const(buf);
sym = asm_label_find(label);
return sym ? sym : asm_new_label1(s1, label, 1, sec->sh_num, 0);
@ -194,7 +196,7 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
break;
case '.':
pe->v = ind;
pe->sym = asm_section_sym(s1, cur_text_section);
pe->sym = asm_section_sym(s1, tcc_state->cur_text_section);
pe->pcrel = 0;
next();
break;
@ -331,7 +333,7 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
/* we also accept defined symbols in the same section */
pe->v += esym1->st_value - esym2->st_value;
pe->sym = NULL;
} else if (esym2->st_shndx == cur_text_section->sh_num) {
} else if (esym2->st_shndx == tcc_state->cur_text_section->sh_num) {
/* When subtracting a defined symbol in current section
this actually makes the value PC-relative. */
pe->v += 0 - esym2->st_value;
@ -439,7 +441,7 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local,
static Sym* asm_new_label(TCCState *s1, int label, int is_local)
{
return asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
return asm_new_label1(s1, label, is_local, tcc_state->cur_text_section->sh_num, ind);
}
/* Set the value of LABEL to that of some expression (possibly
@ -463,9 +465,9 @@ static Sym* set_symbol(TCCState *s1, int label)
static void use_section1(TCCState *s1, Section *sec)
{
cur_text_section->data_offset = ind;
cur_text_section = sec;
ind = cur_text_section->data_offset;
tcc_state->cur_text_section->data_offset = ind;
tcc_state->cur_text_section = sec;
ind = tcc_state->cur_text_section->data_offset;
}
static void use_section(TCCState *s1, const char *name)
@ -478,16 +480,16 @@ static void use_section(TCCState *s1, const char *name)
static void push_section(TCCState *s1, const char *name)
{
Section *sec = find_section(s1, name);
sec->prev = cur_text_section;
sec->prev = tcc_state->cur_text_section;
use_section1(s1, sec);
}
static void pop_section(TCCState *s1)
{
Section *prev = cur_text_section->prev;
Section *prev = tcc_state->cur_text_section->prev;
if (!prev)
tcc_error(".popsection without .pushsection");
cur_text_section->prev = NULL;
tcc_state->cur_text_section->prev = NULL;
use_section1(s1, prev);
}
@ -498,7 +500,7 @@ static void asm_parse_directive(TCCState *s1, int global)
uint8_t *ptr;
/* assembler directive */
sec = cur_text_section;
sec = tcc_state->cur_text_section;
switch(tok) {
case TOK_ASMDIR_align:
case TOK_ASMDIR_balign:
@ -677,7 +679,7 @@ static void asm_parse_directive(TCCState *s1, int global)
n = e.v;
esym = elfsym(e.sym);
if (esym) {
if (esym->st_shndx != cur_text_section->sh_num)
if (esym->st_shndx != tcc_state->cur_text_section->sh_num)
expect("constant or same-section symbol");
n += esym->st_value;
}
@ -889,7 +891,7 @@ static void asm_parse_directive(TCCState *s1, int global)
next();
}
}
last_text_section = cur_text_section;
last_text_section = tcc_state->cur_text_section;
if (tok1 == TOK_ASMDIR_section)
use_section(s1, sname);
else
@ -898,8 +900,8 @@ static void asm_parse_directive(TCCState *s1, int global)
1. new_section normally acts for GCC compatibility and
sets alignment to PTR_SIZE. The assembler behaves different. */
if (old_nb_section != s1->nb_sections) {
cur_text_section->sh_addralign = 1;
cur_text_section->sh_flags = flags;
tcc_state->cur_text_section->sh_addralign = 1;
tcc_state->cur_text_section->sh_flags = flags;
}
}
break;
@ -909,7 +911,7 @@ static void asm_parse_directive(TCCState *s1, int global)
next();
if (!last_text_section)
tcc_error("no previous section referenced");
sec = cur_text_section;
sec = tcc_state->cur_text_section;
use_section1(s1, last_text_section);
last_text_section = sec;
}
@ -1010,11 +1012,11 @@ int tcc_assemble(TCCState *s1, int do_preprocess)
{
int ret;
/* default section is text */
cur_text_section = text_section;
ind = cur_text_section->data_offset;
tcc_state->cur_text_section = tcc_state->text_section;
ind = tcc_state->cur_text_section->data_offset;
nocode_wanted = 0;
ret = tcc_assemble_internal(s1, do_preprocess, 1);
cur_text_section->data_offset = ind;
tcc_state->cur_text_section->data_offset = ind;
return ret;
}
@ -1307,11 +1309,11 @@ void asm_instr(void)
/* We don't allow switching section within inline asm to
bleed out to surrounding code. */
sec = cur_text_section;
sec = tcc_state->cur_text_section;
/* assemble the string with tcc internal assembler */
tcc_assemble_inline(tcc_state, astr.data, astr.size - 1, 0);
cstr_free_s(&astr);
if (sec != cur_text_section) {
if (sec != tcc_state->cur_text_section) {
tcc_warning("inline asm tries to change current section");
use_section1(tcc_state, sec);
}
@ -1348,13 +1350,13 @@ void asm_global_instr(void)
#ifdef ASM_DEBUG
printf("asm_global: \"%s\"\n", (char *)astr->data);
#endif
cur_text_section = text_section;
ind = cur_text_section->data_offset;
tcc_state->cur_text_section = tcc_state->text_section;
ind = tcc_state->cur_text_section->data_offset;
/* assemble the string with tcc internal assembler */
tcc_assemble_inline(tcc_state, astr->data, astr->size - 1, 1);
cur_text_section->data_offset = ind;
tcc_state->cur_text_section->data_offset = ind;
/* restore the current C token */
next();

View file

@ -5,6 +5,7 @@
#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)
@ -66,7 +67,7 @@ coff_load_obj(TCCState *s1, int fd)
for (k = 1; k < s1->nb_sections; k++)
{
if (strcmp(s1->sections[k]->name, buff) != 0)
if (strcmp(s1->sections[k]->old_name, buff) != 0)
{
continue;
}

View file

@ -73,11 +73,11 @@ void tccelf_new(TCCState *s)
dynarray_add(&s->sections, &s->nb_sections, NULL);
/* create standard sections */
text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
s->text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
s->data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
/* create ro data section (make ro after relocation done with GNU_RELRO) */
rodata_section = new_section(s, rdata, SHT_PROGBITS, shf_RELRO);
bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
s->rodata_section = new_section(s, rdata, SHT_PROGBITS, shf_RELRO);
s->bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
common_section->sh_num = SHN_COMMON;
@ -195,7 +195,7 @@ Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
sec = tcc_mallocz(sizeof(Section) + strlen(name));
sec->s1 = s1;
strcpy(sec->name, name);
strcpy(sec->old_name, name);
sec->sh_type = sh_type;
sec->sh_flags = sh_flags;
switch(sh_type) {
@ -318,7 +318,7 @@ static Section *have_section(TCCState *s1, const char *name)
int i;
for(i = 1; i < s1->nb_sections; i++) {
sec = s1->sections[i];
if (!strcmp(name, sec->name))
if (!strcmp(name, sec->old_name))
return sec;
}
return NULL;
@ -582,12 +582,12 @@ int set_elf_sym(Section *s, addr_t value, unsigned long size,
} else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
/* ignore hidden symbols after */
} else if ((esym->st_shndx == SHN_COMMON
|| esym->st_shndx == bss_section->sh_num)
|| esym->st_shndx == s1->bss_section->sh_num)
&& (shndx < SHN_LORESERVE
&& shndx != bss_section->sh_num)) {
&& shndx != s1->bss_section->sh_num)) {
/* data symbol gets precedence over common/bss */
goto do_patch;
} else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
} else if (shndx == SHN_COMMON || shndx == s1->bss_section->sh_num) {
/* data symbol keeps precedence over common/bss */
} else if (s->sh_flags & SHF_DYNSYM) {
/* we accept that two DLL define the same symbol */
@ -632,7 +632,7 @@ void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
sr = s->reloc;
if (!sr) {
/* if no relocation section, create it */
snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->old_name);
/* if the symtab is allocated, then we consider the relocation
are also */
sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
@ -1211,7 +1211,7 @@ static void add_init_array_defines(TCCState *s1, const char *section_name)
s = have_section(s1, section_name);
if (!s || !(s->sh_flags & SHF_ALLOC)) {
end_offset = 0;
s = text_section;
s = s1->text_section;
} else {
end_offset = s->data_offset;
}
@ -1278,9 +1278,9 @@ static void tcc_add_linker_symbols(TCCState *s1)
int i;
Section *s;
set_global_sym(s1, "_etext", text_section, -1);
set_global_sym(s1, "_edata", data_section, -1);
set_global_sym(s1, "_end", bss_section, -1);
set_global_sym(s1, "_etext", s1->text_section, -1);
set_global_sym(s1, "_edata", s1->data_section, -1);
set_global_sym(s1, "_end", s1->bss_section, -1);
/* horrible new standard ldscript defines */
add_init_array_defines(s1, ".preinit_array");
@ -1295,7 +1295,7 @@ static void tcc_add_linker_symbols(TCCState *s1)
|| s->sh_type == SHT_STRTAB)) {
/* check if section name can be expressed in C */
const char *p0, *p;
p0 = s->name;
p0 = s->old_name;
if (*p0 == '.')
++p0;
p = p0;
@ -1324,9 +1324,9 @@ void resolve_common_syms(TCCState *s1)
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
if (sym->st_shndx == SHN_COMMON) {
/* symbol alignment is in st_value for SHN_COMMONs */
sym->st_value = section_add(bss_section, sym->st_size,
sym->st_value = section_add(s1->bss_section, sym->st_size,
sym->st_value);
sym->st_shndx = bss_section->sh_num;
sym->st_shndx = s1->bss_section->sh_num;
}
}
@ -1478,7 +1478,7 @@ static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) {
k = 0x10;
} else if (s->sh_type == SHT_STRTAB && strcmp(s->name, ".stabstr")) {
} else if (s->sh_type == SHT_STRTAB && strcmp(s->old_name, ".stabstr")) {
k = 0x11;
if (i == nb_sections - 1) /* ".shstrtab" assumed to stay last */
k = 0xff;
@ -1878,7 +1878,7 @@ static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr)
else
ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
if (ehdr.e_entry == (addr_t)-1)
ehdr.e_entry = text_section->sh_addr;
ehdr.e_entry = s1->text_section->sh_addr;
if (s1->nb_errors)
return -1;
}
@ -2117,7 +2117,7 @@ static void alloc_sec_names(TCCState *s1, int is_obj)
if (is_obj)
s->sh_size = s->data_offset;
if (s->sh_size || s == strsec || (s->sh_flags & SHF_ALLOC) || is_obj)
s->sh_name = put_elf_str(strsec, s->name);
s->sh_name = put_elf_str(strsec, s->old_name);
}
strsec->sh_size = strsec->data_offset;
}
@ -2195,8 +2195,8 @@ int tcc_object_type(int fd, ElfW(Ehdr) *h)
} else if (size >= 8) {
if (0 == memcmp(h, ARMAG, 8))
return AFF_BINTYPE_AR;
else if (((FILHDR *)h)->f_magic == F_MACH_I386)
return (AFF_BINTYPE_COFF);
/* else if (((FILHDR *)h)->f_magic == F_MACH_I386)
return (AFF_BINTYPE_COFF);*/
}
return 0;
}
@ -2295,12 +2295,12 @@ invalid:
/* find corresponding section, if any */
for(j = 1; j < s1->nb_sections;j++) {
s = s1->sections[j];
if (strcmp(s->name, sh_name))
if (strcmp(s->old_name, sh_name))
continue;
if (sh->sh_type != s->sh_type
&& strcmp (s->name, ".eh_frame")
&& strcmp (s->old_name, ".eh_frame")
) {
tcc_error_noabort("section type conflict: %s %02x <> %02x", s->name, sh->sh_type, s->sh_type);
tcc_error_noabort("section type conflict: %s %02x <> %02x", s->old_name, sh->sh_type, s->sh_type);
goto the_end;
}
if (!strncmp(sh_name, ".gnu.linkonce", 13)) {
@ -2339,8 +2339,8 @@ invalid:
}
/* align end of section */
/* This is needed if we compile a c file after this */
if (s == text_section || s == data_section || s == rodata_section ||
s == bss_section || s == common_section)
if (s == s1->text_section || s == s1->data_section || s == s1->rodata_section ||
s == s1->bss_section || s == common_section)
s->data_offset += -s->data_offset & (s->sh_addralign - 1);
next: ;
}

View file

@ -398,7 +398,7 @@ void tccgen_finish(TCCState *s1)
nb_temp_local_vars = 0;
global_label_stack = NULL;
local_label_stack = NULL;
cur_text_section = NULL;
tcc_state->cur_text_section = NULL;
sym_free_first = NULL;
}
@ -524,7 +524,7 @@ void put_extern_sym2(Sym *sym, int sh_num,
void put_extern_sym(Sym *sym, Section *s, addr_t value, unsigned long size)
{
if (nocode_wanted && (NODATA_WANTED || (s && s == cur_text_section)))
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);
}
@ -535,7 +535,7 @@ void greloca(Section *s, Sym *sym, unsigned long offset, int type,
{
int c = 0;
if (nocode_wanted && s == cur_text_section)
if (nocode_wanted && s == tcc_state->cur_text_section)
return;
if (sym) {
@ -778,7 +778,7 @@ void label_pop(Sym **ptop, Sym *slast, int keep)
if (s->c) {
/* define corresponding symbol. A size of
1 is put. */
put_extern_sym(s, cur_text_section, s->jnext, 1);
put_extern_sym(s, tcc_state->cur_text_section, s->jnext, 1);
}
}
/* remove label */
@ -1623,7 +1623,7 @@ int gv(int rc)
(vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
/* CPUs usually cannot use float constants, so we store them
generically in data segment */
init_params p = { rodata_section, 0, NULL };
init_params p = { tcc_state->rodata_section, 0, NULL };
unsigned long offset;
size = type_size(&vtop->type, &align);
if (NODATA_WANTED)
@ -5213,7 +5213,7 @@ void unary(void)
mk_pointer(&type);
type.t |= VT_ARRAY;
memset(&ad, 0, sizeof(AttributeDef));
ad.section = rodata_section;
ad.section = tcc_state->rodata_section;
decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
break;
case TOK_SOTYPE:
@ -7724,11 +7724,11 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
while ((tp->t & (VT_BTYPE|VT_ARRAY)) == (VT_PTR|VT_ARRAY))
tp = &tp->ref->type;
if (tp->t & VT_CONSTANT) {
sec = rodata_section;
sec = tcc_state->rodata_section;
} else if (has_init) {
sec = data_section;
sec = tcc_state->data_section;
} else if (tcc_state->nocommon)
sec = bss_section;
sec = tcc_state->bss_section;
}
if (sec) {
@ -7843,9 +7843,9 @@ static void gen_function(Sym *sym)
cur_scope = root_scope = &f;
nocode_wanted = 0;
ind = cur_text_section->data_offset;
ind = tcc_state->cur_text_section->data_offset;
if (sym->a.aligned) {
size_t newoff = section_add(cur_text_section, 0,
size_t newoff = section_add(tcc_state->cur_text_section, 0,
1 << (sym->a.aligned - 1));
gen_fill_nops(newoff - ind);
}
@ -7856,7 +7856,7 @@ static void gen_function(Sym *sym)
func_var = sym->type.ref->f.func_type == FUNC_ELLIPSIS;
/* NOTE: we patch the symbol size later */
put_extern_sym(sym, cur_text_section, ind, 0);
put_extern_sym(sym, tcc_state->cur_text_section, ind, 0);
if (sym->type.ref->f.func_ctor)
add_array (tcc_state, ".init_array", sym->c);
@ -7885,13 +7885,13 @@ static void gen_function(Sym *sym)
/* patch symbol size */
elfsym(sym)->st_size = ind - func_ind;
cur_text_section->data_offset = ind;
tcc_state->cur_text_section->data_offset = ind;
local_scope = 0;
label_pop(&global_label_stack, NULL, 0);
sym_pop(&all_cleanups, NULL, 0);
/* It's better to crash than to generate wrong code */
cur_text_section = NULL;
tcc_state->cur_text_section = NULL;
funcname = ""; /* for safety */
func_vt.t = VT_VOID; /* for safety */
func_var = 0; /* for safety */
@ -7924,7 +7924,7 @@ static void gen_inline_functions(TCCState *s)
tccpp_putfile(fn->filename);
begin_macro(fn->func_str, 1);
next();
cur_text_section = text_section;
tcc_state->cur_text_section = tcc_state->text_section;
gen_function(sym);
end_macro();
@ -8126,11 +8126,11 @@ static int decl(int l)
skip_or_save_block(&fn->func_str);
} else {
/* compute text section */
cur_text_section = ad.section;
if (!cur_text_section)
cur_text_section = text_section;
else if (cur_text_section->sh_num > bss_section->sh_num)
cur_text_section->sh_flags = text_section->sh_flags;
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;
gen_function(sym);
}
break;

View file

@ -1,120 +0,0 @@
/*
* TCC - Tiny C Compiler
*
* Copyright (c) 2001-2004 Fabrice Bellard
* Copyright (c) 2025 d0p1
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#include "libtcc.h"
static const char help_str[] =
"Tiny C Compiler "PACKAGE_VERSION" - Copyright (C) 2001-2006 Fabrice Bellard\n"
"Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n"
"General options:\n"
" -c compile only - generate an object file\n"
" -o outfile set output filename\n"
" -fflag set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n"
" -Wwarning set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"
" -w disable all warnings\n"
" -v --version show version\n"
" -vv show search paths or loaded files\n"
" -h -hh show this, show more help\n"
" -bench show compilation statistics\n"
" - use stdin pipe as infile\n"
" @listfile read arguments from listfile\n"
"Preprocessor options:\n"
" -Idir add include path 'dir'\n"
" -Dsym[=val] define 'sym' with value 'val'\n"
" -Usym undefine 'sym'\n"
" -E preprocess only\n"
"Linker options:\n"
" -Ldir add library path 'dir'\n"
" -llib link with dynamic or static library 'lib'\n"
" -r generate (relocatable) object file\n"
" -Wl,-opt[=val] set linker option (see tcc -hh)\n"
"Misc. options:\n"
" -std=version define __STDC_VERSION__ according to version (c11/gnu11)\n"
" -x[c|a|b|n] specify type of the next infile (C,ASM,BIN,NONE)\n"
" -nostdinc do not use standard system include paths\n"
" -nostdlib do not link with standard crt and libraries\n"
" -Bdir set tcc's private include/library dir\n"
" -M[M]D generate make dependency file [ignore system files]\n"
" -M[M] as above but no other output\n"
" -MF file specify dependency file name\n"
"Tools:\n"
" create library : tcc -ar [crstvx] lib [files]\n"
;
static const char help_more_str[] =
"Tiny C Compiler "PACKAGE_VERSION" - More Options\n"
"Special options:\n"
" -P -P1 with -E: no/alternative #line output\n"
" -dD -dM with -E: output #define directives\n"
" -pthread same as -D_REENTRANT and -lpthread\n"
" -On same as -D__OPTIMIZE__ for n > 0\n"
" -Wp,-opt same as -opt\n"
" -include file include 'file' above each input file\n"
" -isystem dir add 'dir' to system include path\n"
" -dumpversion print version\n"
" -print-search-dirs print search paths\n"
"Ignored options:\n"
" -arch -C --param -pedantic -pipe -s -traditional -g -static -shared\n"
"-W[no-]... warnings:\n"
" all turn on some (*) warnings\n"
" error[=warning] stop after warning (any or specified)\n"
" write-strings strings are const\n"
" unsupported warn about ignored options, pragmas, etc.\n"
" implicit-function-declaration warn for missing prototype (*)\n"
" discarded-qualifiers warn when const is dropped (*)\n"
"-f[no-]... flags:\n"
" unsigned-char default char is unsigned\n"
" signed-char default char is signed\n"
" common use common section instead of bss\n"
" leading-underscore decorate extern symbols\n"
" ms-extensions allow anonymous struct in struct\n"
" dollars-in-identifiers allow '$' in C symbols\n"
" reverse-funcargs evaluate function arguments right to left\n"
" gnu89-inline 'extern inline' is like 'static inline'\n"
" asynchronous-unwind-tables create eh_frame section [on]\n"
"-m... target specific options:\n"
" ms-bitfields use MSVC bitfield layout\n"
"-Wl,... linker options:\n"
" -nostdlib do not link with standard crt/libs\n"
" -[no-]whole-archive load lib(s) fully/only as needed\n"
" -image-base= -Ttext= set base address of executable\n"
" -section-alignment= set section alignment in executable\n"
" -enable-new-dtags set DT_RUNPATH instead of DT_RPATH\n"
" -oformat=[coff,binary] set executable output format\n"
" -init= -fini= -Map= -as-needed -O (ignored)\n"
"Predefined macros:\n"
" tcc -E -dM - < /dev/null\n"
"See also the manual for more details.\n"
;
static const char version_str[] = "tcc version "PACKAGE_VERSION" (i386)\n";
int
main(int argc, char *argv[])
{
TCCState *s;
}

View file

@ -123,7 +123,7 @@ no_ar:
while (fread(&arhdr, 1, sizeof(arhdr), fh) == sizeof(arhdr)) {
char *p, *e;
if (memcmp(arhdr.fmag, ARFMAG, 2))
if (memcmp(arhdr.fmag, ARCHIVE_FILMAG, 2))
goto no_ar;
p = arhdr.name;
for (e = p + sizeof arhdr.name; e > p && e[-1] == ' ';)