From ca1e24c395aff88509e9e96dfcdc33c923504843 Mon Sep 17 00:00:00 2001 From: d0p1 Date: Tue, 11 Feb 2025 13:07:04 +0100 Subject: [PATCH] Further refactor code --- configure.ac | 13 + libtcc/Makefile.am | 2 +- libtcc/include/libtcc.h | 4 +- libtcc/include/tcc.h | 67 +--- libtcc/include/tcc/io.h | 29 ++ libtcc/include/tcc/memory.h | 27 ++ libtcc/include/tcc/object.h | 10 + libtcc/include/tcc/object/archive.h | 6 +- libtcc/include/tcc/object/binary.h | 4 + libtcc/include/tcc/object/coff.h | 6 +- libtcc/include/tcc/option.h | 6 +- libtcc/include/tcc/path.h | 19 + .../cstr.h => include/tcc/utils/cstring.h} | 10 +- libtcc/libtcc.c | 285 +-------------- libtcc/memory.c | 339 ++++++++++++++++++ libtcc/object.c | 13 + libtcc/object/archive.c | 13 + libtcc/object/coff.c | 55 +++ libtcc/option.c | 17 +- libtcc/path.c | 47 +++ libtcc/tcc_internal.h | 4 - libtcc/tcccoff.c | 9 +- libtcc/tccelf.c | 17 +- libtcc/tccgen.c | 6 + libtcc/tccpp.c | 10 +- libtcc1/Makefile.am | 4 + tcc/tcc.c | 2 + tcc/tcctools.c | 5 +- 28 files changed, 661 insertions(+), 368 deletions(-) create mode 100644 libtcc/include/tcc/io.h create mode 100644 libtcc/include/tcc/memory.h create mode 100644 libtcc/include/tcc/object.h create mode 100644 libtcc/include/tcc/object/binary.h create mode 100644 libtcc/include/tcc/path.h rename libtcc/{utils/cstr.h => include/tcc/utils/cstring.h} (74%) create mode 100644 libtcc/memory.c create mode 100644 libtcc/object.c create mode 100644 libtcc/object/archive.c create mode 100644 libtcc/object/coff.c create mode 100644 libtcc/path.c delete mode 100644 libtcc/tcc_internal.h diff --git a/configure.ac b/configure.ac index 8d46a549..3af6183e 100644 --- a/configure.ac +++ b/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=], [enable memory debuging with (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 diff --git a/libtcc/Makefile.am b/libtcc/Makefile.am index f3866f8d..e5d18acb 100644 --- a/libtcc/Makefile.am +++ b/libtcc/Makefile.am @@ -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 diff --git a/libtcc/include/libtcc.h b/libtcc/include/libtcc.h index fdb0c5c0..cce32834 100644 --- a/libtcc/include/libtcc.h +++ b/libtcc/include/libtcc.h @@ -1,11 +1,13 @@ #ifndef LIBTCC_H # define LIBTCC_H 1 +# include + # 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. */ diff --git a/libtcc/include/tcc.h b/libtcc/include/tcc.h index da843f4d..dc0d3443 100644 --- a/libtcc/include/tcc.h +++ b/libtcc/include/tcc.h @@ -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 #include #include +#include /* -------------------------------------------- */ @@ -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); diff --git a/libtcc/include/tcc/io.h b/libtcc/include/tcc/io.h new file mode 100644 index 00000000..188f02b8 --- /dev/null +++ b/libtcc/include/tcc/io.h @@ -0,0 +1,29 @@ +#ifndef TCC_IO_H +# define TCC_IO_H 1 + +# include + +# 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 */ \ No newline at end of file diff --git a/libtcc/include/tcc/memory.h b/libtcc/include/tcc/memory.h new file mode 100644 index 00000000..18831186 --- /dev/null +++ b/libtcc/include/tcc/memory.h @@ -0,0 +1,27 @@ +#ifndef TCC_MEMORY_H +# define TCC_MEMORY_H 1 + +# include + +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 */ \ No newline at end of file diff --git a/libtcc/include/tcc/object.h b/libtcc/include/tcc/object.h new file mode 100644 index 00000000..fc66c39e --- /dev/null +++ b/libtcc/include/tcc/object.h @@ -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 */ \ No newline at end of file diff --git a/libtcc/include/tcc/object/archive.h b/libtcc/include/tcc/object/archive.h index c560dd72..76dcc64c 100644 --- a/libtcc/include/tcc/object/archive.h +++ b/libtcc/include/tcc/object/archive.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 */ \ No newline at end of file +#endif /* !TCC_OBJECT_AR_H */ \ No newline at end of file diff --git a/libtcc/include/tcc/object/binary.h b/libtcc/include/tcc/object/binary.h new file mode 100644 index 00000000..07d27afb --- /dev/null +++ b/libtcc/include/tcc/object/binary.h @@ -0,0 +1,4 @@ +#ifndef TCC_OBJECT_BINARY_H +# define TCC_OBJECT_BINARY_H 1 + +#endif /* TCC_OBJECT_BINARY_H */ \ No newline at end of file diff --git a/libtcc/include/tcc/object/coff.h b/libtcc/include/tcc/object/coff.h index e3af72cc..6d1197a5 100644 --- a/libtcc/include/tcc/object/coff.h +++ b/libtcc/include/tcc/object/coff.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 @@ -66,4 +66,4 @@ typedef struct COFFSectionHeader { * @} */ -#endif /* !LIBTCC_COFF_H */ \ No newline at end of file +#endif /* !TCC_COFF_H */ \ No newline at end of file diff --git a/libtcc/include/tcc/option.h b/libtcc/include/tcc/option.h index 9e87c709..4609089e 100644 --- a/libtcc/include/tcc/option.h +++ b/libtcc/include/tcc/option.h @@ -1,5 +1,5 @@ -#ifndef LIBTCC_OPTION_H -# define LIBTCC_OPTION_H 1 +#ifndef TCC_OPTION_H +# define TCC_OPTION_H 1 # include @@ -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 */ \ No newline at end of file +#endif /* TCC_OPTION_H */ \ No newline at end of file diff --git a/libtcc/include/tcc/path.h b/libtcc/include/tcc/path.h new file mode 100644 index 00000000..1152cc0e --- /dev/null +++ b/libtcc/include/tcc/path.h @@ -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 */ \ No newline at end of file diff --git a/libtcc/utils/cstr.h b/libtcc/include/tcc/utils/cstring.h similarity index 74% rename from libtcc/utils/cstr.h rename to libtcc/include/tcc/utils/cstring.h index 142c13b7..1d4c816d 100644 --- a/libtcc/utils/cstr.h +++ b/libtcc/include/tcc/utils/cstring.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 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 */ \ No newline at end of file +#endif /* !TCC_UTILS_CSTRING_H */ \ No newline at end of file diff --git a/libtcc/libtcc.c b/libtcc/libtcc.c index 8f414382..d3193255 100644 --- a/libtcc/libtcc.c +++ b/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 +#include +#include +#include #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 diff --git a/libtcc/memory.c b/libtcc/memory.c new file mode 100644 index 00000000..9df5351d --- /dev/null +++ b/libtcc/memory.c @@ -0,0 +1,339 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include +#include +#include +#include + +#include + +#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 */ diff --git a/libtcc/object.c b/libtcc/object.c new file mode 100644 index 00000000..9e91dd05 --- /dev/null +++ b/libtcc/object.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include + +int +tcc_object_type(int fd, void *h) +{ + size_t size; + + + return (0); +} \ No newline at end of file diff --git a/libtcc/object/archive.c b/libtcc/object/archive.c new file mode 100644 index 00000000..821bbe69 --- /dev/null +++ b/libtcc/object/archive.c @@ -0,0 +1,13 @@ +#include +#include + +int +tcc_load_archive(TCCState *s1, int fd, int alacarte) +{ + ArchiveFileHeader hdr; + int size; + int len; + size_t file_offset; + + return (0); +} \ No newline at end of file diff --git a/libtcc/object/coff.c b/libtcc/object/coff.c new file mode 100644 index 00000000..bb0d523c --- /dev/null +++ b/libtcc/object/coff.c @@ -0,0 +1,55 @@ +#include +#include + +#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) +{ + +} \ No newline at end of file diff --git a/libtcc/option.c b/libtcc/option.c index 047f8f41..0dc221a7 100644 --- a/libtcc/option.c +++ b/libtcc/option.c @@ -1,8 +1,13 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + #include #include #include #include +#include #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; diff --git a/libtcc/path.c b/libtcc/path.c new file mode 100644 index 00000000..a90beca1 --- /dev/null +++ b/libtcc/path.c @@ -0,0 +1,47 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ +#ifdef HAVE_LIBGEN_H +# include +#endif /* HAVE_LIBGEN_H */ +#include +#include + +/* 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)); +} diff --git a/libtcc/tcc_internal.h b/libtcc/tcc_internal.h deleted file mode 100644 index 48272031..00000000 --- a/libtcc/tcc_internal.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef TCC_INTERNAL_H -# define TCC_INTERNAL_H 1 - -#endif /* !TCC_INTERNAL_H */ \ No newline at end of file diff --git a/libtcc/tcccoff.c b/libtcc/tcccoff.c index 53971c56..ae071710 100644 --- a/libtcc/tcccoff.c +++ b/libtcc/tcccoff.c @@ -1,4 +1,10 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + #include +#include +#include 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); } \ No newline at end of file diff --git a/libtcc/tccelf.c b/libtcc/tccelf.c index 11f33b80..37a909aa 100644 --- a/libtcc/tccelf.c +++ b/libtcc/tccelf.c @@ -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 +#include +#include #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) diff --git a/libtcc/tccgen.c b/libtcc/tccgen.c index e32c2d9f..c932819c 100644 --- a/libtcc/tccgen.c +++ b/libtcc/tccgen.c @@ -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 +#include #include "utils/string.h" #include "token.h" diff --git a/libtcc/tccpp.c b/libtcc/tccpp.c index bcb9a602..e1ef80be 100644 --- a/libtcc/tccpp.c +++ b/libtcc/tccpp.c @@ -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 +#include +#include #include "utils/string.h" #include "token.h" #include @@ -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__) diff --git a/libtcc1/Makefile.am b/libtcc1/Makefile.am index 4fac7564..49487ba3 100644 --- a/libtcc1/Makefile.am +++ b/libtcc1/Makefile.am @@ -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 diff --git a/tcc/tcc.c b/tcc/tcc.c index 15b34ad1..c6481f9d 100644 --- a/tcc/tcc.c +++ b/tcc/tcc.c @@ -24,6 +24,8 @@ #include #include +#include +#include #include "tcctools.h" static const char help_str[] = diff --git a/tcc/tcctools.c b/tcc/tcctools.c index 5282c7db..445be78a 100644 --- a/tcc/tcctools.c +++ b/tcc/tcctools.c @@ -28,9 +28,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "tcc.h" - +#include +#include #include +#include static unsigned long le2belong(unsigned long ul) { return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) +