Further refactor code
This commit is contained in:
parent
db4e043cd9
commit
ca1e24c395
28 changed files with 661 additions and 368 deletions
13
configure.ac
13
configure.ac
|
@ -25,5 +25,18 @@ AC_CHECK_INCLUDES_DEFAULT
|
|||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_C_BIGENDIAN
|
||||
AC_C_CHAR_UNSIGNED
|
||||
|
||||
AC_CHECK_HEADERS([
|
||||
libgen.h
|
||||
sys/queue.h
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE([memory_debug],
|
||||
[AS_HELP_STRING([--enable-memory-debug=<level>], [enable memory debuging with <level> (1, 2, 3)])])
|
||||
|
||||
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_OUTPUT
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
noinst_LIBRARIES = libtcc.a
|
||||
libtcc_a_SOURCES = libtcc.c option.c tccpp.c tccgen.c \
|
||||
libtcc_a_SOURCES = libtcc.c option.c path.c memory.c tccpp.c tccgen.c \
|
||||
tccasm.c tccelf.c \
|
||||
i386/gen.c i386/link.c \
|
||||
i386/asm.c tcccoff.c
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#ifndef LIBTCC_H
|
||||
# define LIBTCC_H 1
|
||||
|
||||
# include <stddef.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif /* __cplusplus */
|
||||
|
||||
typedef void *TCCReallocFunc(void *ptr, unsigned long size);
|
||||
typedef void *TCCReallocFunc(void *ptr, size_t size);
|
||||
/**
|
||||
* @brief set custom allocator for all allocations (optional), NULL for default.
|
||||
*/
|
||||
|
|
|
@ -83,18 +83,6 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|||
#define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# define IS_DIRSEP(c) (c == '/' || c == '\\')
|
||||
# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
|
||||
# define PATHCMP stricmp
|
||||
# define PATHSEP ";"
|
||||
#else
|
||||
# define IS_DIRSEP(c) (c == '/')
|
||||
# define IS_ABSPATH(p) IS_DIRSEP(p[0])
|
||||
# define PATHCMP strcmp
|
||||
# define PATHSEP ":"
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/* parser debug */
|
||||
|
@ -180,6 +168,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|||
#include <libtcc.h>
|
||||
#include <tcc/elf.h>
|
||||
#include <tcc/coff.h>
|
||||
#include <tcc/utils/cstring.h>
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
|
@ -200,7 +189,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|||
# define REL_SECTION_FMT ".rel%s"
|
||||
|
||||
/* target address type */
|
||||
#define addr_t ElfW(Addr)
|
||||
typedef uint32_t addr_t;
|
||||
#define ElfSym ElfW(Sym)
|
||||
|
||||
#define LONG_SIZE 4
|
||||
|
@ -232,12 +221,6 @@ typedef struct TokenSym {
|
|||
|
||||
typedef int nwchar_t;
|
||||
|
||||
typedef struct CString {
|
||||
int size; /* size in bytes */
|
||||
int size_allocated;
|
||||
char *data; /* nwchar_t* in cases */
|
||||
} CString;
|
||||
|
||||
/* type definition */
|
||||
typedef struct CType {
|
||||
int t;
|
||||
|
@ -341,6 +324,14 @@ typedef struct Section {
|
|||
unsigned char *data; /* section data */
|
||||
unsigned long data_allocated; /* used for realloc() handling */
|
||||
TCCState *s1;
|
||||
|
||||
/**/
|
||||
char *c_name[8];
|
||||
addr_t c_addr;
|
||||
int32_t c_flags;
|
||||
|
||||
/**/
|
||||
|
||||
int sh_name; /* elf section name (only used during output) */
|
||||
int sh_num; /* elf section number */
|
||||
int sh_type; /* elf section type */
|
||||
|
@ -549,10 +540,7 @@ struct TCCState {
|
|||
|
||||
char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */
|
||||
char *rpath; /* as specified on the command line (-Wl,-rpath=) */
|
||||
char *elf_entryname; /* "_start" unless set */
|
||||
char *init_symbol; /* symbols to call at load-time (not used currently) */
|
||||
char *fini_symbol; /* symbols to call at unload-time (not used currently) */
|
||||
char *mapfile; /* create a mapfile (not used currently) */
|
||||
char *entryname; /* "_start" unless set */
|
||||
|
||||
/* output type, see TCC_OUTPUT_XXX */
|
||||
int output_type;
|
||||
|
@ -771,30 +759,6 @@ extern struct TCCState *tcc_state;
|
|||
extern void** stk_data;
|
||||
extern int nb_stk_data;
|
||||
|
||||
/* public functions currently used by the tcc main function */
|
||||
PUB_FUNC char *tcc_basename(const char *name);
|
||||
PUB_FUNC char *tcc_fileextension (const char *name);
|
||||
|
||||
/* all allocations - even MEM_DEBUG - use these */
|
||||
PUB_FUNC void tcc_free(void *ptr);
|
||||
PUB_FUNC void *tcc_malloc(unsigned long size);
|
||||
PUB_FUNC void *tcc_mallocz(unsigned long size);
|
||||
PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
|
||||
PUB_FUNC char *tcc_strdup(const char *str);
|
||||
|
||||
#ifdef MEM_DEBUG
|
||||
#define tcc_free(ptr) tcc_free_debug(ptr)
|
||||
#define tcc_malloc(size) tcc_malloc_debug(size, __FILE__, __LINE__)
|
||||
#define tcc_mallocz(size) tcc_mallocz_debug(size, __FILE__, __LINE__)
|
||||
#define tcc_realloc(ptr,size) tcc_realloc_debug(ptr, size, __FILE__, __LINE__)
|
||||
#define tcc_strdup(str) tcc_strdup_debug(str, __FILE__, __LINE__)
|
||||
PUB_FUNC void tcc_free_debug(void *ptr);
|
||||
PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line);
|
||||
PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line);
|
||||
PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line);
|
||||
PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
|
||||
#endif
|
||||
|
||||
PUB_FUNC int _tcc_error_noabort(const char *fmt, ...) __attribute__ ((format (printf, (1), (2))));
|
||||
PUB_FUNC __attribute__((noreturn)) void _tcc_error(const char *fmt, ...) __attribute__ ((format (printf, (1), (2))));
|
||||
PUB_FUNC void _tcc_warning(const char *fmt, ...) __attribute__ ((format (printf, (1), (2))));
|
||||
|
@ -804,14 +768,6 @@ PUB_FUNC void _tcc_warning(const char *fmt, ...) __attribute__ ((format (printf,
|
|||
/* other utilities */
|
||||
void dynarray_add(void *ptab, int *nb_ptr, void *data);
|
||||
void dynarray_reset(void *pp, int *n);
|
||||
void cstr_ccat(CString *cstr, int ch);
|
||||
void cstr_cat(CString *cstr, const char *str, int len);
|
||||
void cstr_wccat(CString *cstr, int ch);
|
||||
void cstr_new(CString *cstr);
|
||||
void cstr_free(CString *cstr);
|
||||
int cstr_printf(CString *cs, const char *fmt, ...) __attribute__ ((format (printf, (2), (3))));
|
||||
int cstr_vprintf(CString *cstr, const char *fmt, va_list ap);
|
||||
void cstr_reset(CString *cstr);
|
||||
void tcc_open_bf(TCCState *s1, const char *filename, int initlen);
|
||||
int tcc_open(TCCState *s1, const char *filename);
|
||||
void tcc_close(void);
|
||||
|
@ -1071,7 +1027,6 @@ 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_object_type(int fd, ElfW(Ehdr) *h);
|
||||
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);
|
||||
|
|
29
libtcc/include/tcc/io.h
Normal file
29
libtcc/include/tcc/io.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef TCC_IO_H
|
||||
# define TCC_IO_H 1
|
||||
|
||||
# include <stdint.h>
|
||||
|
||||
# define IO_BUF_SIZE 8192
|
||||
|
||||
typedef struct BufferedFile {
|
||||
uint8_t *buf_ptr;
|
||||
uint8_t *buf_end;
|
||||
int fd;
|
||||
struct BufferedFile *prev;
|
||||
int line_num; /** current line number - here to simplify code */
|
||||
int line_ref; /** tcc -E: last printed line */
|
||||
int ifndef_macro; /** #ifndef macro / #endif search */
|
||||
int ifndef_macro_saved; /** saved ifndef_macro */
|
||||
int *ifdef_stack_ptr; /** ifdef_stack value at the start of the file */
|
||||
int include_next_index; /** next search path */
|
||||
int prev_tok_flags; /** saved tok_flags */
|
||||
char *filename[1024]; /** filename */
|
||||
char *true_filename; /** filename not modified by # line directive */
|
||||
unsigned char unget[4];
|
||||
unsigned char buffer[1]; /** extra size for CH_EOB char */
|
||||
} BufferedFile;
|
||||
|
||||
# define CH_EOB '\\' /** end of buffer or '\0' char in file */
|
||||
# define CH_EOF (-1) /** end of file */
|
||||
|
||||
#endif /* !TCC_IO_H */
|
27
libtcc/include/tcc/memory.h
Normal file
27
libtcc/include/tcc/memory.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef TCC_MEMORY_H
|
||||
# define TCC_MEMORY_H 1
|
||||
|
||||
# include <stddef.h>
|
||||
|
||||
void tcc_free(void *ptr);
|
||||
void *tcc_malloc(size_t size);
|
||||
void *tcc_mallocz(size_t size);
|
||||
void *tcc_realloc(void *ptr, size_t size);
|
||||
char *tcc_strdup(const char *str);
|
||||
|
||||
# ifdef TCC_MEMORY_DEBUG
|
||||
# define tcc_free(ptr) tcc_free_debug(ptr);
|
||||
# define tcc_malloc(size) tcc_malloc_debug(size, __FILE__, __LINE__)
|
||||
# define tcc_mallocz(size) tcc_mallocz_debug(size, __FILE__, __LINE__)
|
||||
# define tcc_realloc(ptr, size) tcc_realloc_debug(ptr, size, __FILE__, __LINE__)
|
||||
# define tcc_strdup(str) tcc_strdup_debug(str, __FILE__, __LINE__)
|
||||
|
||||
void tcc_free_debug(void *ptr);
|
||||
void *tcc_malloc_debug(size_t size, const char *file, int line);
|
||||
void *tcc_mallocz_debug(size_t size, const char *file, int line);
|
||||
void *tcc_realloc_debug(void *ptr, size_t size, const char *file, int line);
|
||||
void *tcc_strdup_debug(const char *str, const char *file, int line);
|
||||
void tcc_memcheck(int d);
|
||||
# endif /* TCC_MEMORY_DEBUG */
|
||||
|
||||
#endif /* !TCC_MEMORY_H */
|
10
libtcc/include/tcc/object.h
Normal file
10
libtcc/include/tcc/object.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef TCC_OBJECT_H
|
||||
# define TCC_OBJECT_H 1
|
||||
|
||||
# define TCC_BINTYPE_NONE 0
|
||||
# define TCC_BINTYPE_COFF 1
|
||||
# define TCC_BINTYPE_ARCHIVE 2
|
||||
|
||||
int tcc_object_type(int fd, void *h);
|
||||
|
||||
#endif /* !TCC_OBJECT_H */
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef LIBTCC_OBJECT_ARCHIVE_H
|
||||
# define LIBTCC_OBJECT_ARCHIVE_H 1
|
||||
#ifndef TCC_OBJECT_ARCHIVE_H
|
||||
# define TCC_OBJECT_ARCHIVE_H 1
|
||||
|
||||
/**
|
||||
* @defgroup object_archive UNIX Archive
|
||||
|
@ -32,4 +32,4 @@ typedef struct Archive {
|
|||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !LIBTCC_OBJECT_AR_H */
|
||||
#endif /* !TCC_OBJECT_AR_H */
|
4
libtcc/include/tcc/object/binary.h
Normal file
4
libtcc/include/tcc/object/binary.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#ifndef TCC_OBJECT_BINARY_H
|
||||
# define TCC_OBJECT_BINARY_H 1
|
||||
|
||||
#endif /* TCC_OBJECT_BINARY_H */
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef LIBTCC_OBJECT_COFF_H
|
||||
# define LIBTCC_OBJECT_COFF_H 1
|
||||
#ifndef TCC_OBJECT_COFF_H
|
||||
# define TCC_OBJECT_COFF_H 1
|
||||
|
||||
# include <stdint.h>
|
||||
|
||||
|
@ -66,4 +66,4 @@ typedef struct COFFSectionHeader {
|
|||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !LIBTCC_COFF_H */
|
||||
#endif /* !TCC_COFF_H */
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef LIBTCC_OPTION_H
|
||||
# define LIBTCC_OPTION_H 1
|
||||
#ifndef TCC_OPTION_H
|
||||
# define TCC_OPTION_H 1
|
||||
|
||||
# include <stdint.h>
|
||||
|
||||
|
@ -23,4 +23,4 @@ typedef struct TCCState TCCState;
|
|||
int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind);
|
||||
void tcc_add_options(TCCOption *opts);
|
||||
|
||||
#endif /* LIBTCC_OPTION_H */
|
||||
#endif /* TCC_OPTION_H */
|
19
libtcc/include/tcc/path.h
Normal file
19
libtcc/include/tcc/path.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef TCC_PATH_H
|
||||
# define TCC_PATH_H 1
|
||||
|
||||
#ifdef _WIN32
|
||||
# define IS_DIRSEP(c) (c == '/' || c == '\\')
|
||||
# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
|
||||
# define PATHCMP stricmp
|
||||
# define PATHSEP ";"
|
||||
#else
|
||||
# define IS_DIRSEP(c) (c == '/')
|
||||
# define IS_ABSPATH(p) IS_DIRSEP(p[0])
|
||||
# define PATHCMP strcmp
|
||||
# define PATHSEP ":"
|
||||
#endif
|
||||
|
||||
char *tcc_basename(const char *name);
|
||||
char *tcc_fileextension (const char *name);
|
||||
|
||||
#endif /* !TCC_PATH_H */
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef LIBTCC_UTILS_CSTR_H
|
||||
# define LIBTCC_UTILS_CSTR_H 1
|
||||
#ifndef TCC_UTILS_CSTRING_H
|
||||
# define TCC_UTILS_CSTRING_H 1
|
||||
|
||||
# include <stdarg.h>
|
||||
|
||||
typedef struct CString {
|
||||
int size;
|
||||
int size; /** size in bytes */
|
||||
int size_allocated;
|
||||
char *data;
|
||||
} CString;
|
||||
|
@ -14,8 +14,8 @@ void cstr_cat(CString *cstr, const char *str, int len);
|
|||
void cstr_wccat(CString *cstr, int ch);
|
||||
void cstr_new(CString *cstr);
|
||||
void cstr_free(CString *cstr);
|
||||
int cstr_printf(CString *cs, const char *fmt, ...) __attribute__ ((format (printf, (2), (3))));
|
||||
int cstr_printf(CString *cs, const char *fmt, ...) __attribute__((format(printf, (2), (3))));
|
||||
int cstr_vprintf(CString *cstr, const char *fmt, va_list ap);
|
||||
void cstr_reset(CString *cstr);
|
||||
|
||||
#endif /* !LIBTCC_UTILS_CSTR_H */
|
||||
#endif /* !TCC_UTILS_CSTRING_H */
|
285
libtcc/libtcc.c
285
libtcc/libtcc.c
|
@ -18,7 +18,14 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <tcc.h>
|
||||
#include <tcc/path.h>
|
||||
#include <tcc/memory.h>
|
||||
#include <tcc/object.h>
|
||||
#include "utils/string.h"
|
||||
|
||||
/********************************************************/
|
||||
|
@ -79,26 +86,6 @@ PUB_FUNC void tcc_exit_state(TCCState *s1)
|
|||
POST_SEM(&tcc_compile_sem);
|
||||
}
|
||||
|
||||
/* extract the basename of a file */
|
||||
PUB_FUNC char *tcc_basename(const char *name)
|
||||
{
|
||||
char *p = strchr(name, 0);
|
||||
while (p > name && !IS_DIRSEP(p[-1]))
|
||||
--p;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* extract extension part of a file
|
||||
*
|
||||
* (if no extension, return pointer to end-of-string)
|
||||
*/
|
||||
PUB_FUNC char *tcc_fileextension (const char *name)
|
||||
{
|
||||
char *b = tcc_basename(name);
|
||||
char *e = strrchr(b, '.');
|
||||
return e ? e : strchr(b, 0);
|
||||
}
|
||||
|
||||
char *tcc_load_text(int fd)
|
||||
{
|
||||
int len = lseek(fd, 0, SEEK_END);
|
||||
|
@ -111,247 +98,6 @@ char *tcc_load_text(int fd)
|
|||
/********************************************************/
|
||||
/* memory management */
|
||||
|
||||
static void *default_reallocator(void *ptr, unsigned long size)
|
||||
{
|
||||
void *ptr1;
|
||||
if (size == 0) {
|
||||
free(ptr);
|
||||
ptr1 = NULL;
|
||||
}
|
||||
else {
|
||||
ptr1 = realloc(ptr, size);
|
||||
if (!ptr1) {
|
||||
fprintf(stderr, "memory full\n");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
return ptr1;
|
||||
}
|
||||
|
||||
/* global so that every tcc_alloc()/tcc_free() call doesn't need to be changed */
|
||||
static void *(*reallocator)(void*, unsigned long) = default_reallocator;
|
||||
|
||||
void tcc_set_realloc(TCCReallocFunc *realloc)
|
||||
{
|
||||
reallocator = realloc ? realloc : default_reallocator;
|
||||
}
|
||||
|
||||
/* in case MEM_DEBUG is #defined */
|
||||
#undef tcc_free
|
||||
#undef tcc_malloc
|
||||
#undef tcc_realloc
|
||||
#undef tcc_mallocz
|
||||
#undef tcc_strdup
|
||||
|
||||
PUB_FUNC void tcc_free(void *ptr)
|
||||
{
|
||||
reallocator(ptr, 0);
|
||||
}
|
||||
|
||||
PUB_FUNC void *tcc_malloc(unsigned long size)
|
||||
{
|
||||
return reallocator(0, size);
|
||||
}
|
||||
|
||||
PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
|
||||
{
|
||||
return reallocator(ptr, size);
|
||||
}
|
||||
|
||||
PUB_FUNC void *tcc_mallocz(unsigned long size)
|
||||
{
|
||||
void *ptr;
|
||||
ptr = tcc_malloc(size);
|
||||
if (size)
|
||||
memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
PUB_FUNC char *tcc_strdup(const char *str)
|
||||
{
|
||||
char *ptr;
|
||||
ptr = tcc_malloc(strlen(str) + 1);
|
||||
strcpy(ptr, str);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#ifdef MEM_DEBUG
|
||||
|
||||
#define MEM_DEBUG_MAGIC1 0xFEEDDEB1
|
||||
#define MEM_DEBUG_MAGIC2 0xFEEDDEB2
|
||||
#define MEM_DEBUG_MAGIC3 0xFEEDDEB3
|
||||
#define MEM_DEBUG_FILE_LEN 40
|
||||
#define MEM_DEBUG_CHECK3(header) \
|
||||
((mem_debug_header_t*)((char*)header + header->size))->magic3
|
||||
#define MEM_USER_PTR(header) \
|
||||
((char *)header + offsetof(mem_debug_header_t, magic3))
|
||||
#define MEM_HEADER_PTR(ptr) \
|
||||
(mem_debug_header_t *)((char*)ptr - offsetof(mem_debug_header_t, magic3))
|
||||
|
||||
struct mem_debug_header {
|
||||
unsigned magic1;
|
||||
unsigned size;
|
||||
struct mem_debug_header *prev;
|
||||
struct mem_debug_header *next;
|
||||
int line_num;
|
||||
char file_name[MEM_DEBUG_FILE_LEN + 1];
|
||||
unsigned magic2;
|
||||
__attribute__((aligned(16))) unsigned char magic3[4];
|
||||
};
|
||||
|
||||
typedef struct mem_debug_header mem_debug_header_t;
|
||||
|
||||
TCC_SEM(static mem_sem);
|
||||
static mem_debug_header_t *mem_debug_chain;
|
||||
static unsigned mem_cur_size;
|
||||
static unsigned mem_max_size;
|
||||
static int nb_states;
|
||||
|
||||
static mem_debug_header_t *malloc_check(void *ptr, const char *msg)
|
||||
{
|
||||
mem_debug_header_t * header = MEM_HEADER_PTR(ptr);
|
||||
if (header->magic1 != MEM_DEBUG_MAGIC1 ||
|
||||
header->magic2 != MEM_DEBUG_MAGIC2 ||
|
||||
read32le(MEM_DEBUG_CHECK3(header)) != MEM_DEBUG_MAGIC3 ||
|
||||
header->size == (unsigned)-1) {
|
||||
fprintf(stderr, "%s check failed\n", msg);
|
||||
if (header->magic1 == MEM_DEBUG_MAGIC1)
|
||||
fprintf(stderr, "%s:%u: block allocated here.\n",
|
||||
header->file_name, header->line_num);
|
||||
exit(1);
|
||||
}
|
||||
return header;
|
||||
}
|
||||
|
||||
PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
|
||||
{
|
||||
int ofs;
|
||||
mem_debug_header_t *header;
|
||||
if (!size)
|
||||
return NULL;
|
||||
header = tcc_malloc(sizeof(mem_debug_header_t) + size);
|
||||
header->magic1 = MEM_DEBUG_MAGIC1;
|
||||
header->magic2 = MEM_DEBUG_MAGIC2;
|
||||
header->size = size;
|
||||
write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3);
|
||||
header->line_num = line;
|
||||
ofs = strlen(file) - MEM_DEBUG_FILE_LEN;
|
||||
strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN);
|
||||
header->file_name[MEM_DEBUG_FILE_LEN] = 0;
|
||||
WAIT_SEM(&mem_sem);
|
||||
header->next = mem_debug_chain;
|
||||
header->prev = NULL;
|
||||
if (header->next)
|
||||
header->next->prev = header;
|
||||
mem_debug_chain = header;
|
||||
mem_cur_size += size;
|
||||
if (mem_cur_size > mem_max_size)
|
||||
mem_max_size = mem_cur_size;
|
||||
POST_SEM(&mem_sem);
|
||||
return MEM_USER_PTR(header);
|
||||
}
|
||||
|
||||
PUB_FUNC void tcc_free_debug(void *ptr)
|
||||
{
|
||||
mem_debug_header_t *header;
|
||||
if (!ptr)
|
||||
return;
|
||||
header = malloc_check(ptr, "tcc_free");
|
||||
WAIT_SEM(&mem_sem);
|
||||
mem_cur_size -= header->size;
|
||||
header->size = (unsigned)-1;
|
||||
if (header->next)
|
||||
header->next->prev = header->prev;
|
||||
if (header->prev)
|
||||
header->prev->next = header->next;
|
||||
if (header == mem_debug_chain)
|
||||
mem_debug_chain = header->next;
|
||||
POST_SEM(&mem_sem);
|
||||
tcc_free(header);
|
||||
}
|
||||
|
||||
PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line)
|
||||
{
|
||||
void *ptr;
|
||||
ptr = tcc_malloc_debug(size,file,line);
|
||||
if (size)
|
||||
memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line)
|
||||
{
|
||||
mem_debug_header_t *header;
|
||||
int mem_debug_chain_update = 0;
|
||||
|
||||
if (!ptr)
|
||||
return tcc_malloc_debug(size, file, line);
|
||||
if (!size) {
|
||||
tcc_free_debug(ptr);
|
||||
return NULL;
|
||||
}
|
||||
header = malloc_check(ptr, "tcc_realloc");
|
||||
WAIT_SEM(&mem_sem);
|
||||
mem_cur_size -= header->size;
|
||||
mem_debug_chain_update = (header == mem_debug_chain);
|
||||
header = tcc_realloc(header, sizeof(mem_debug_header_t) + size);
|
||||
header->size = size;
|
||||
write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3);
|
||||
if (header->next)
|
||||
header->next->prev = header;
|
||||
if (header->prev)
|
||||
header->prev->next = header;
|
||||
if (mem_debug_chain_update)
|
||||
mem_debug_chain = header;
|
||||
mem_cur_size += size;
|
||||
if (mem_cur_size > mem_max_size)
|
||||
mem_max_size = mem_cur_size;
|
||||
POST_SEM(&mem_sem);
|
||||
return MEM_USER_PTR(header);
|
||||
}
|
||||
|
||||
PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line)
|
||||
{
|
||||
char *ptr;
|
||||
ptr = tcc_malloc_debug(strlen(str) + 1, file, line);
|
||||
strcpy(ptr, str);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
PUB_FUNC void tcc_memcheck(int d)
|
||||
{
|
||||
WAIT_SEM(&mem_sem);
|
||||
nb_states += d;
|
||||
if (0 == nb_states && mem_cur_size) {
|
||||
mem_debug_header_t *header = mem_debug_chain;
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n",
|
||||
mem_cur_size, mem_max_size);
|
||||
while (header) {
|
||||
fprintf(stderr, "%s:%u: error: %u bytes leaked\n",
|
||||
header->file_name, header->line_num, header->size);
|
||||
header = header->next;
|
||||
}
|
||||
fflush(stderr);
|
||||
mem_cur_size = 0;
|
||||
mem_max_size = 0;
|
||||
mem_debug_chain = NULL;
|
||||
#if MEM_DEBUG-0 == 2
|
||||
exit(2);
|
||||
#endif
|
||||
}
|
||||
POST_SEM(&mem_sem);
|
||||
}
|
||||
|
||||
/* restore the debug versions */
|
||||
#define tcc_free(ptr) tcc_free_debug(ptr)
|
||||
#define tcc_malloc(size) tcc_malloc_debug(size, __FILE__, __LINE__)
|
||||
#define tcc_mallocz(size) tcc_mallocz_debug(size, __FILE__, __LINE__)
|
||||
#define tcc_realloc(ptr,size) tcc_realloc_debug(ptr, size, __FILE__, __LINE__)
|
||||
#define tcc_strdup(str) tcc_strdup_debug(str, __FILE__, __LINE__)
|
||||
|
||||
#endif /* MEM_DEBUG */
|
||||
|
||||
#ifdef _WIN32
|
||||
# define realpath(file, buf) _fullpath(buf, file, 260)
|
||||
#endif
|
||||
|
@ -699,7 +445,7 @@ TCCState *tcc_new(void)
|
|||
TCCState *s;
|
||||
|
||||
s = tcc_mallocz(sizeof(TCCState));
|
||||
#ifdef MEM_DEBUG
|
||||
#ifdef TCC_MEMORY_DEBUG
|
||||
tcc_memcheck(1);
|
||||
#endif
|
||||
|
||||
|
@ -714,7 +460,7 @@ TCCState *tcc_new(void)
|
|||
s->ms_extensions = 1;
|
||||
s->unwind_tables = 1;
|
||||
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
#ifdef __CHAR_UNSIGNED__
|
||||
s->char_is_unsigned = 1;
|
||||
#endif
|
||||
s->seg_size = 32;
|
||||
|
@ -745,10 +491,7 @@ void tcc_delete(TCCState *s1)
|
|||
|
||||
tcc_free(s1->tcc_lib_path);;
|
||||
tcc_free(s1->rpath);
|
||||
tcc_free(s1->elf_entryname);
|
||||
tcc_free(s1->init_symbol);
|
||||
tcc_free(s1->fini_symbol);
|
||||
tcc_free(s1->mapfile);
|
||||
tcc_free(s1->entryname);
|
||||
tcc_free(s1->outfile);
|
||||
tcc_free(s1->deps_outfile);
|
||||
dynarray_reset(&s1->files, &s1->nb_files);
|
||||
|
@ -759,7 +502,7 @@ void tcc_delete(TCCState *s1)
|
|||
cstr_free(&s1->cmdline_incl);
|
||||
cstr_free(&s1->linker_arg);
|
||||
tcc_free(s1);
|
||||
#ifdef MEM_DEBUG
|
||||
#ifdef TCC_MEMORY_DEBUG
|
||||
tcc_memcheck(-1);
|
||||
#endif
|
||||
}
|
||||
|
@ -989,6 +732,10 @@ void tcc_set_lib_path(TCCState *s, const char *path)
|
|||
/********************************************************/
|
||||
/* options parser */
|
||||
|
||||
#ifdef TCC_MEMORY_DEBUG
|
||||
extern size_t mem_max_size;
|
||||
#endif /* TCC_MEMORY_DEBUG */
|
||||
|
||||
PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time)
|
||||
{
|
||||
if (!total_time)
|
||||
|
@ -1005,7 +752,7 @@ PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time)
|
|||
s1->total_output[2],
|
||||
s1->total_output[3]
|
||||
);
|
||||
#ifdef MEM_DEBUG
|
||||
#ifdef TCC_MEMORY_DEBUG
|
||||
fprintf(stderr, "# memory usage");
|
||||
fprintf(stderr, " %d max (bytes)\n", mem_max_size);
|
||||
#endif
|
||||
|
|
339
libtcc/memory.c
Normal file
339
libtcc/memory.c
Normal file
|
@ -0,0 +1,339 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <tcc.h>
|
||||
|
||||
#ifdef TCC_MEMORY_DEBUG
|
||||
# undef tcc_free
|
||||
# undef tcc_malloc
|
||||
# undef tcc_mallocz
|
||||
# undef tcc_realloc
|
||||
# undef tcc_strdup
|
||||
#endif /* TCC_MEMORY_DEBUG */
|
||||
|
||||
static void *
|
||||
default_reallocator(void *ptr, size_t size)
|
||||
{
|
||||
void *ptr1;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
free(ptr);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ptr1 = realloc(ptr, size);
|
||||
if (ptr1 == NULL)
|
||||
{
|
||||
fprintf(stderr, "memory full\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return (ptr1);
|
||||
}
|
||||
|
||||
static TCCReallocFunc *reallocator = default_reallocator;
|
||||
|
||||
void
|
||||
tcc_set_realloc(TCCReallocFunc *my_realloc)
|
||||
{
|
||||
if (my_realloc == NULL)
|
||||
{
|
||||
reallocator = default_reallocator;
|
||||
return;
|
||||
}
|
||||
|
||||
reallocator = my_realloc;
|
||||
}
|
||||
|
||||
void
|
||||
tcc_free(void *ptr)
|
||||
{
|
||||
reallocator(ptr, 0);
|
||||
}
|
||||
|
||||
void *
|
||||
tcc_malloc(size_t size)
|
||||
{
|
||||
return (reallocator(NULL, size));
|
||||
}
|
||||
|
||||
void *
|
||||
tcc_mallocz(size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ptr = tcc_malloc(size);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
memset(ptr, 0, size);
|
||||
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
void *
|
||||
tcc_realloc(void *ptr, size_t size)
|
||||
{
|
||||
return (reallocator(ptr, size));
|
||||
}
|
||||
|
||||
char *
|
||||
tcc_strdup(const char *str)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
ptr = tcc_malloc(strlen(str) + 1);
|
||||
strcpy(ptr, str);
|
||||
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
#ifdef TCC_MEMORY_DEBUG
|
||||
|
||||
# define MEMORY_DEBUG_MAGIC1 0xFEEDDEB1
|
||||
# define MEMORY_DEBUG_MAGIC2 0xFEEDDEB2
|
||||
# define MEMORY_DEBUG_MAGIC3 0xFEEDDEB3
|
||||
|
||||
# define MEMORY_DEBUG_FILE_LEN 40
|
||||
|
||||
# define MEMORY_DEBUG_CHECK3(hdr) \
|
||||
((MemoryDebugHeader *)((uint8_t *)hdr + header->size))->magic3
|
||||
|
||||
# define MEMORY_USER_PTR(hdr) \
|
||||
((uint8_t *)header + offsetof(MemoryDebugHeader, magic3))
|
||||
|
||||
# define MEMORY_HEADER_PTR(ptr) \
|
||||
(MemoryDebugHeader *)((uint8_t *)ptr - offsetof(MemoryDebugHeader, magic3))
|
||||
|
||||
typedef struct MemoryDebugHeader {
|
||||
uint32_t magic1;
|
||||
size_t size;
|
||||
struct MemoryDebugHeader *prev;
|
||||
struct MemoryDebugHeader *next;
|
||||
int linenum;
|
||||
char filename[MEMORY_DEBUG_FILE_LEN + 1];
|
||||
uint32_t magic2;
|
||||
__attribute__((aligned(16))) uint8_t magic3[4];
|
||||
} MemoryDebugHeader;
|
||||
|
||||
TCC_SEM(static mem_sem);
|
||||
static MemoryDebugHeader *mem_debug_chain;
|
||||
static size_t mem_cur_size;
|
||||
size_t mem_max_size;
|
||||
static int nb_states;
|
||||
|
||||
static MemoryDebugHeader *
|
||||
malloc_check(void *ptr, const char *msg)
|
||||
{
|
||||
MemoryDebugHeader *header;
|
||||
|
||||
header = MEMORY_HEADER_PTR(ptr);
|
||||
if (header->magic1 != MEMORY_DEBUG_MAGIC1
|
||||
|| header->magic2 != MEMORY_DEBUG_MAGIC2
|
||||
|| read32le(MEMORY_DEBUG_CHECK3(header)) != MEMORY_DEBUG_MAGIC3
|
||||
|| header->size == (size_t)-1)
|
||||
{
|
||||
fprintf(stderr, "%s check failed\n", msg);
|
||||
if (header->magic1 == MEMORY_DEBUG_MAGIC1)
|
||||
{
|
||||
fprintf(stderr, "%s:%u: block allocated here.\n",
|
||||
header->filename, header->linenum);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return (header);
|
||||
}
|
||||
|
||||
void
|
||||
tcc_free_debug(void *ptr)
|
||||
{
|
||||
MemoryDebugHeader *header;
|
||||
|
||||
if (ptr == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
header = malloc_check(ptr, "tcc_free");
|
||||
|
||||
WAIT_SEM(&mem_sem);
|
||||
|
||||
mem_cur_size -= header->size;
|
||||
header->size = (size_t)-1;
|
||||
if (header->next)
|
||||
{
|
||||
header->next->prev = header->prev;
|
||||
}
|
||||
if (header->prev)
|
||||
{
|
||||
header->prev->next = header->next;
|
||||
}
|
||||
if (header == mem_debug_chain)
|
||||
{
|
||||
mem_debug_chain = header->next;
|
||||
}
|
||||
|
||||
POST_SEM(&mem_sem);
|
||||
|
||||
tcc_free(header);
|
||||
}
|
||||
|
||||
void *
|
||||
tcc_malloc_debug(size_t size, const char *file, int line)
|
||||
{
|
||||
int ofs;
|
||||
MemoryDebugHeader *header;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
header = tcc_malloc(sizeof(MemoryDebugHeader) + size);
|
||||
header->magic1 = MEMORY_DEBUG_MAGIC1;
|
||||
header->magic2 = MEMORY_DEBUG_MAGIC2;
|
||||
header->size = size;
|
||||
write32le(MEMORY_DEBUG_CHECK3(header), MEMORY_DEBUG_MAGIC3);
|
||||
header->linenum = line;
|
||||
ofs = strlen(file) - MEMORY_DEBUG_FILE_LEN;
|
||||
strncpy(header->filename, file + (ofs > 0 ? ofs : 0), MEMORY_DEBUG_FILE_LEN);
|
||||
header->filename[MEMORY_DEBUG_FILE_LEN] = 0;
|
||||
|
||||
WAIT_SEM(&mem_sem);
|
||||
|
||||
header->next = mem_debug_chain;
|
||||
header->prev = NULL;
|
||||
if (header->next)
|
||||
{
|
||||
header->next->prev = header;
|
||||
}
|
||||
mem_debug_chain = header;
|
||||
mem_cur_size += size;
|
||||
if (mem_cur_size > mem_max_size)
|
||||
{
|
||||
mem_max_size = mem_cur_size;
|
||||
}
|
||||
|
||||
POST_SEM(&mem_sem);
|
||||
|
||||
return (MEMORY_USER_PTR(header));
|
||||
}
|
||||
|
||||
void *
|
||||
tcc_mallocz_debug(size_t size, const char *file, int line)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ptr = tcc_malloc_debug(size, file, line);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
memset(ptr, 0, size);
|
||||
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
void *
|
||||
tcc_realloc_debug(void *ptr, size_t size, const char *file, int line)
|
||||
{
|
||||
MemoryDebugHeader *header;
|
||||
int mem_debug_chain_update;
|
||||
|
||||
mem_debug_chain_update = 0;
|
||||
|
||||
if (ptr == NULL)
|
||||
{
|
||||
return (tcc_malloc_debug(size, file, line));
|
||||
}
|
||||
if (size == 0)
|
||||
{
|
||||
tcc_free_debug(ptr);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
header = malloc_check(ptr, "tcc_realloc");
|
||||
|
||||
WAIT_SEM(&mem_sem);
|
||||
|
||||
mem_cur_size -= header->size;
|
||||
mem_debug_chain_update = (header == mem_debug_chain);
|
||||
header = tcc_realloc(header, sizeof(MemoryDebugHeader) + size);
|
||||
header->size = size;
|
||||
write32le(MEMORY_DEBUG_CHECK3(header), MEMORY_DEBUG_MAGIC3);
|
||||
if (header->next)
|
||||
{
|
||||
header->next->prev = header;
|
||||
}
|
||||
if (header->prev)
|
||||
{
|
||||
header->prev->next = header;
|
||||
}
|
||||
if (mem_debug_chain_update)
|
||||
{
|
||||
mem_debug_chain = header;
|
||||
}
|
||||
mem_cur_size += size;
|
||||
if (mem_cur_size > mem_max_size)
|
||||
{
|
||||
mem_max_size = mem_cur_size;
|
||||
}
|
||||
|
||||
POST_SEM(&mem_sem);
|
||||
|
||||
return (MEMORY_USER_PTR(header));
|
||||
}
|
||||
|
||||
char *
|
||||
tcc_strdup_debug(const char *str, const char *file, int line)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
ptr = tcc_malloc_debug(strlen(str) + 1, file, line);
|
||||
strcpy(ptr, str);
|
||||
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
void
|
||||
tcc_memcheck(int d)
|
||||
{
|
||||
MemoryDebugHeader *header;
|
||||
|
||||
WAIT_SEM(&mem_sem);
|
||||
|
||||
nb_states += d;
|
||||
if (0 == nb_states && mem_cur_size)
|
||||
{
|
||||
header = mem_debug_chain;
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n",
|
||||
mem_cur_size, mem_max_size);
|
||||
while (header)
|
||||
{
|
||||
fprintf(stderr, "%s:%u: error: %u bytes leaked\n",
|
||||
header->filename, header->linenum, header->size);
|
||||
header = header->next;
|
||||
}
|
||||
fflush(stderr);
|
||||
mem_cur_size = 0;
|
||||
mem_max_size = 0;
|
||||
mem_debug_chain = NULL;
|
||||
#if TCC_MEMORY_DEBUG-0 == 2
|
||||
exit(2);
|
||||
#endif /* TCC_MEMORY_DEBUG == 2 */
|
||||
}
|
||||
|
||||
POST_SEM(&mem_sem);
|
||||
}
|
||||
|
||||
#endif /* TCC_MEMORY_DEBUG */
|
13
libtcc/object.c
Normal file
13
libtcc/object.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include <tcc.h>
|
||||
#include <tcc/object.h>
|
||||
#include <tcc/object/archive.h>
|
||||
#include <tcc/object/coff.h>
|
||||
|
||||
int
|
||||
tcc_object_type(int fd, void *h)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
|
||||
return (0);
|
||||
}
|
13
libtcc/object/archive.c
Normal file
13
libtcc/object/archive.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include <tcc.h>
|
||||
#include <tcc/object/archive.h>
|
||||
|
||||
int
|
||||
tcc_load_archive(TCCState *s1, int fd, int alacarte)
|
||||
{
|
||||
ArchiveFileHeader hdr;
|
||||
int size;
|
||||
int len;
|
||||
size_t file_offset;
|
||||
|
||||
return (0);
|
||||
}
|
55
libtcc/object/coff.c
Normal file
55
libtcc/object/coff.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include <tcc.h>
|
||||
#include <tcc/object/coff.h>
|
||||
|
||||
#define COFF_DEFAULT_ENTRYNAME "_start"
|
||||
|
||||
int
|
||||
tcc_output_coff(TCCState *s1, FILE *f)
|
||||
{
|
||||
COFFFileHeader coffhdr;
|
||||
AOutHeader aouthdr;
|
||||
COFFSectionHeader coffsec;
|
||||
const char *entry_name = COFF_DEFAULT_ENTRYNAME;
|
||||
|
||||
memset(&coffhdr, 0, sizeof(COFFFileHeader));
|
||||
|
||||
coffhdr.flags = COFF_F_LITTLE | COFF_F_LNNO;
|
||||
coffhdr.magic = COFF_MAGIC;
|
||||
coffhdr.nscns = s1->nb_sections;
|
||||
|
||||
if (s1->output_type == TCC_OUTPUT_EXE)
|
||||
{
|
||||
coffhdr.flags |= COFF_F_RELFLG | COFF_F_EXEC | COFF_F_LSYMS;
|
||||
coffhdr.nsyms = 0;
|
||||
|
||||
memset(&aouthdr, 0, sizeof(AOutHeader));
|
||||
|
||||
aouthdr.magic = AOUT_ZMAGIC;
|
||||
coffhdr.opthdr = sizeof(AOutHeader);
|
||||
|
||||
if (s1->entryname != NULL)
|
||||
{
|
||||
entry_name = s1->entryname;
|
||||
}
|
||||
aouthdr.entry = get_sym_addr(s1, entry_name, 1, 0);
|
||||
|
||||
if (s1->nb_errors)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
coff_output_object(TCCState *s, const char *filename)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
coff_output_exe(TCCState *s, const char *filename)
|
||||
{
|
||||
|
||||
}
|
|
@ -1,8 +1,13 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <tcc.h>
|
||||
#include <tcc/option.h>
|
||||
#include <tcc/memory.h>
|
||||
#include "utils/string.h"
|
||||
|
||||
# define F_WD_ALL 0x0001 /* warning is activated when using -Wall */
|
||||
|
@ -105,6 +110,7 @@ static const TCCOption options[] = {
|
|||
{"MMD", OPTION_MMD, 0},
|
||||
{"MP", OPTION_MP, 0},
|
||||
{"x", OPTION_x, 0},
|
||||
{"ar", OPTION_ar, 0},
|
||||
|
||||
/* ignored (silently, except after -Wunsupported) */
|
||||
{"arch", 0, TCC_OPTION_HAS_ARG},
|
||||
|
@ -321,20 +327,11 @@ set_linker(TCCState *s, const char *option)
|
|||
s->nostdlib = 1;
|
||||
} else if (link_option(option, "e=", &p)
|
||||
|| link_option(option, "entry=", &p)) {
|
||||
copy_linker_arg(&s->elf_entryname, p, 0);
|
||||
} else if (link_option(option, "fini=", &p)) {
|
||||
copy_linker_arg(&s->fini_symbol, p, 0);
|
||||
ignoring = 1;
|
||||
copy_linker_arg(&s->entryname, p, 0);
|
||||
} else if (link_option(option, "image-base=", &p)
|
||||
|| link_option(option, "Ttext=", &p)) {
|
||||
s->text_addr = strtoull(p, &end, 16);
|
||||
s->has_text_addr = 1;
|
||||
} else if (link_option(option, "init=", &p)) {
|
||||
copy_linker_arg(&s->init_symbol, p, 0);
|
||||
ignoring = 1;
|
||||
} else if (link_option(option, "Map=", &p)) {
|
||||
copy_linker_arg(&s->mapfile, p, 0);
|
||||
ignoring = 1;
|
||||
} else if (link_option(option, "oformat=", &p)) {
|
||||
if (strstart("elf32-", &p)) {
|
||||
s->output_format = TCC_OUTPUT_FORMAT_ELF;
|
||||
|
|
47
libtcc/path.c
Normal file
47
libtcc/path.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#ifdef HAVE_LIBGEN_H
|
||||
# include <libgen.h>
|
||||
#endif /* HAVE_LIBGEN_H */
|
||||
#include <string.h>
|
||||
#include <tcc/path.h>
|
||||
|
||||
/* extract the basename of a file */
|
||||
char *
|
||||
tcc_basename(const char *name)
|
||||
{
|
||||
#ifdef HAVE_LIBGEN_H
|
||||
return (basename((char *)name));
|
||||
#else
|
||||
char *p;
|
||||
|
||||
p = strchr(name, 0);
|
||||
while (p > name && !IS_DIRSEP(p[-1]))
|
||||
{
|
||||
--p;
|
||||
}
|
||||
return (p);
|
||||
#endif /* HAVE_LIBGEN_H */
|
||||
}
|
||||
|
||||
/* extract extension part of a file
|
||||
*
|
||||
* (if no extension, return pointer to end-of-string)
|
||||
*/
|
||||
char *
|
||||
tcc_fileextension(const char *name)
|
||||
{
|
||||
const char *b;
|
||||
char *e;
|
||||
|
||||
b = tcc_basename(name);
|
||||
e = strrchr(tcc_basename(name), '.');
|
||||
|
||||
if (e)
|
||||
{
|
||||
return (e);
|
||||
}
|
||||
|
||||
return (strchr(b, 0));
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
#ifndef TCC_INTERNAL_H
|
||||
# define TCC_INTERNAL_H 1
|
||||
|
||||
#endif /* !TCC_INTERNAL_H */
|
|
@ -1,4 +1,10 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <tcc.h>
|
||||
#include <tcc/path.h>
|
||||
#include <tcc/memory.h>
|
||||
|
||||
static int
|
||||
read_mem(int fd, unsigned offset, void *buffer, unsigned len)
|
||||
|
@ -99,7 +105,8 @@ coff_load_file(TCCState *s1, int fd, const char *fname)
|
|||
}
|
||||
|
||||
int
|
||||
coff_output_file(TCCState *s1, const char *fname)
|
||||
coff_output_file(TCCState *s1, const char *filename)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
|
@ -18,7 +18,13 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <tcc.h>
|
||||
#include <tcc/path.h>
|
||||
#include <tcc/memory.h>
|
||||
|
||||
#include "utils/string.h"
|
||||
|
||||
|
@ -473,12 +479,7 @@ addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
|
|||
int sym_index;
|
||||
ElfW(Sym) *sym;
|
||||
char buf[256];
|
||||
if (forc && s1->leading_underscore
|
||||
#ifdef TCC_TARGET_PE
|
||||
/* win32-32bit stdcall symbols always have _ already */
|
||||
&& !strchr(name, '@')
|
||||
#endif
|
||||
) {
|
||||
if (forc && s1->leading_underscore) {
|
||||
buf[0] = '_';
|
||||
pstrcpy(buf + 1, sizeof(buf) - 1, name);
|
||||
name = buf;
|
||||
|
@ -1872,8 +1873,8 @@ static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr)
|
|||
ehdr.e_type = ET_REL;
|
||||
} else {
|
||||
ehdr.e_type = ET_EXEC;
|
||||
if (s1->elf_entryname)
|
||||
ehdr.e_entry = get_sym_addr(s1, s1->elf_entryname, 1, 0);
|
||||
if (s1->entryname)
|
||||
ehdr.e_entry = get_sym_addr(s1, s1->entryname, 1, 0);
|
||||
else
|
||||
ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
|
||||
if (ehdr.e_entry == (addr_t)-1)
|
||||
|
|
|
@ -18,8 +18,14 @@
|
|||
* 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 <tcc/memory.h>
|
||||
#include "utils/string.h"
|
||||
#include "token.h"
|
||||
|
||||
|
|
|
@ -18,8 +18,14 @@
|
|||
* 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 <tcc/path.h>
|
||||
#include <tcc/memory.h>
|
||||
#include "utils/string.h"
|
||||
#include "token.h"
|
||||
#include <math.h>
|
||||
|
@ -127,12 +133,12 @@ void expect(const char *msg)
|
|||
#define tal_new(a,b,c)
|
||||
#define tal_delete(a)
|
||||
#else
|
||||
#if !defined(MEM_DEBUG)
|
||||
#if !defined(TCC_MEMORY_DEBUG)
|
||||
#define tal_free(al, p) tal_free_impl(al, p)
|
||||
#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size)
|
||||
#define TAL_DEBUG_PARAMS
|
||||
#else
|
||||
#define TAL_DEBUG MEM_DEBUG
|
||||
#define TAL_DEBUG TCC_MEMORY_DEBUG
|
||||
//#define TAL_INFO 1 /* collect and dump allocators stats */
|
||||
#define tal_free(al, p) tal_free_impl(al, p, __FILE__, __LINE__)
|
||||
#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size, __FILE__, __LINE__)
|
||||
|
|
|
@ -4,6 +4,10 @@ noinst_LIBRARIES = libtcc1.a
|
|||
|
||||
libtcc1_a_SOURCES = alloca.S atomic.S builtin.c libtcc1.c stdatomic.c
|
||||
|
||||
libtcc1_a_AR = ../tcc/tcc -ar cr
|
||||
libtcc1_a_DEPENDENCIES = ../tcc/tcc
|
||||
libtcc1_a_RANLIB = @echo
|
||||
|
||||
alloca.o: alloca.S
|
||||
$(COMPILE) -o $@ -c $^ -I$(srcdir)/include
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#include <tcc.h>
|
||||
#include <tcc/option.h>
|
||||
#include <tcc/path.h>
|
||||
#include <tcc/memory.h>
|
||||
#include "tcctools.h"
|
||||
|
||||
static const char help_str[] =
|
||||
|
|
|
@ -28,9 +28,10 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "tcc.h"
|
||||
|
||||
#include <tcc.h>
|
||||
#include <tcc/path.h>
|
||||
#include <tcc/object/archive.h>
|
||||
#include <tcc/memory.h>
|
||||
|
||||
static unsigned long le2belong(unsigned long ul) {
|
||||
return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) +
|
||||
|
|
Loading…
Reference in a new issue