X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/73c04bcfe1096173b00431f0cdc742894b15eef0..f59164e3d128c7675a4d3934206346a3384e53a5:/icuSources/tools/genccode/genccode.c diff --git a/icuSources/tools/genccode/genccode.c b/icuSources/tools/genccode/genccode.c index 31a53711..58f5c2e8 100644 --- a/icuSources/tools/genccode/genccode.c +++ b/icuSources/tools/genccode/genccode.c @@ -1,27 +1,25 @@ /* -******************************************************************************* -* -* Copyright (C) 1999-2006, International Business Machines -* Corporation and others. All Rights Reserved. -* -******************************************************************************* -* file name: gennames.c -* encoding: US-ASCII -* tab size: 8 (not used) -* indentation:4 -* -* created on: 1999nov01 -* created by: Markus W. Scherer -* -* This program reads a binary file and creates a C source code file -* with a byte array that contains the data of the binary file. -* -* 12/09/1999 weiv Added multiple file handling -*/ + ******************************************************************************* + * Copyright (C) 1999-2016, International Business Machines + * Corporation and others. All Rights Reserved. + ******************************************************************************* + * file name: gennames.c + * encoding: US-ASCII + * tab size: 8 (not used) + * indentation:4 + * + * created on: 1999nov01 + * created by: Markus W. Scherer + * + * This program reads a binary file and creates a C source code file + * with a byte array that contains the data of the binary file. + * + * 12/09/1999 weiv Added multiple file handling + */ #include "unicode/utypes.h" -#ifdef U_WINDOWS +#if U_PLATFORM_HAS_WIN32_API # define VC_EXTRALEAN # define WIN32_LEAN_AND_MEAN # define NOUSER @@ -30,19 +28,22 @@ # define NOMCX #include #include +#endif -/* _M_IA64 should be defined in windows.h */ -#if defined(_M_IA64) -# define ICU_OBJECT_MACHINE_TYPE IMAGE_FILE_MACHINE_IA64 -# define ICU_ENTRY_OFFSET 0 -#elif defined(_M_AMD64) -# define ICU_OBJECT_MACHINE_TYPE IMAGE_FILE_MACHINE_AMD64 -# define ICU_ENTRY_OFFSET 0 -#else -# define ICU_OBJECT_MACHINE_TYPE IMAGE_FILE_MACHINE_I386 -# define ICU_ENTRY_OFFSET 1 +#if U_PLATFORM_IS_LINUX_BASED && U_HAVE_ELF_H +# define U_ELF #endif +#ifdef U_ELF +# include +# if defined(ELFCLASS64) +# define U_ELF64 +# endif + /* Old elf.h headers may not have EM_X86_64, or have EM_X8664 instead. */ +# ifndef EM_X86_64 +# define EM_X86_64 62 +# endif +# define ICU_ENTRY_OFFSET 0 #endif #include @@ -54,44 +55,9 @@ #include "toolutil.h" #include "unicode/uclean.h" #include "uoptions.h" +#include "pkg_genc.h" -#define MAX_COLUMN ((uint32_t)(0xFFFFFFFFU)) - -static uint32_t column=MAX_COLUMN; - -#ifdef U_WINDOWS -#define CAN_GENERATE_OBJECTS -#endif - -/* prototypes --------------------------------------------------------------- */ - -static void -writeCCode(const char *filename, const char *destdir); - -static void -writeAssemblyCode(const char *filename, const char *destdir); - -#ifdef CAN_GENERATE_OBJECTS -static void -writeObjectCode(const char *filename, const char *destdir); -#endif - -static void -getOutFilename(const char *inFilename, const char *destdir, char *outFilename, char *entryName, const char *newSuffix); - -static void -write8(FileStream *out, uint8_t byte); - -static void -write32(FileStream *out, uint32_t byte); - -#ifdef OS400 -static void -write8str(FileStream *out, uint8_t byte); -#endif -/* -------------------------------------------------------------------------- */ - -enum { +enum { kOptHelpH = 0, kOptHelpQuestionMark, kOptDestDir, @@ -99,112 +65,12 @@ enum { kOptEntryPoint, #ifdef CAN_GENERATE_OBJECTS kOptObject, + kOptMatchArch, #endif kOptFilename, kOptAssembly }; -/* -Creating Template Files for New Platforms - -Let the cc compiler help you get started. -Compile this program - const unsigned int x[5] = {1, 2, 0xdeadbeef, 0xffffffff, 16}; -with the -S option to produce assembly output. - -For example, this will generate array.s: -gcc -S array.c - -This will produce a .s file that may look like this: - - .file "array.c" - .version "01.01" -gcc2_compiled.: - .globl x - .section .rodata - .align 4 - .type x,@object - .size x,20 -x: - .long 1 - .long 2 - .long -559038737 - .long -1 - .long 16 - .ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-85)" - -which gives a starting point that will compile, and can be transformed -to become the template, generally with some consulting of as docs and -some experimentation. - -If you want ICU to automatically use this assembly, you should -specify "GENCCODE_ASSEMBLY=-a name" in the specific config/mh-* file, -where the name is the compiler or platform that you used in this -assemblyHeader data structure. -*/ -static const struct AssemblyType { - const char *name; - const char *header; - const char *beginLine; -} assemblyHeader[] = { - {"gcc", - ".globl %s\n" - "\t.section .note.GNU-stack,\"\",@progbits\n" - "\t.section .rodata\n" - "\t.align 8\n" /* Either align 8 bytes or 2^8 (256) bytes. 8 bytes is needed. */ - "\t.type %s,@object\n" - "%s:\n\n", - - ".long " - }, - {"gcc-darwin", - /*"\t.section __TEXT,__text,regular,pure_instructions\n" - "\t.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32\n"*/ - ".globl _%s\n" - "\t.data\n" - "\t.const\n" - "\t.align 4\n" /* 1<<4 = 16 */ - "_%s:\n\n", - - ".long " - }, - {"gcc-cygwin", - ".globl _%s\n" - "\t.section .rodata\n" - "\t.align 8\n" /* Either align 8 bytes or 2^8 (256) bytes. 8 bytes is needed. */ - "_%s:\n\n", - - ".long " - }, - {"sun", - "\t.section \".rodata\"\n" - "\t.align 8\n" - ".globl %s\n" - "%s:\n", - - ".word " - }, - {"xlc", - ".globl %s{RO}\n" - "\t.toc\n" - "%s:\n" - "\t.csect %s{RO}, 4\n", - - ".long " - }, - {"aCC", - "\t.SPACE $TEXT$\n" - "\t.SUBSPA $LIT$\n" - "%s\n" - "\t.EXPORT %s\n" - "\t.ALIGN 16\n", - - ".WORD " - } -}; - -static int32_t assemblyHeaderIndex = -1; - static UOption options[]={ /*0*/UOPTION_HELP_H, UOPTION_HELP_QUESTION_MARK, @@ -213,23 +79,27 @@ static UOption options[]={ UOPTION_DEF("entrypoint", 'e', UOPT_REQUIRES_ARG), #ifdef CAN_GENERATE_OBJECTS /*5*/UOPTION_DEF("object", 'o', UOPT_NO_ARG), + UOPTION_DEF("match-arch", 'm', UOPT_REQUIRES_ARG), #endif UOPTION_DEF("filename", 'f', UOPT_REQUIRES_ARG), UOPTION_DEF("assembly", 'a', UOPT_REQUIRES_ARG) }; +#define CALL_WRITECCODE 'c' +#define CALL_WRITEASSEMBLY 'a' +#define CALL_WRITEOBJECT 'o' extern int main(int argc, char* argv[]) { UBool verbose = TRUE; - int32_t idx; + char writeCode; U_MAIN_INIT_ARGS(argc, argv); options[kOptDestDir].value = "."; /* read command line options */ - argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options); - + argc=u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options); + /* error handling, printing usage message */ if(argc<0) { fprintf(stderr, @@ -245,36 +115,30 @@ main(int argc, char* argv[]) { "\t-h or -? or --help this usage text\n" "\t-d or --destdir destination directory, followed by the path\n" "\t-n or --name symbol prefix, followed by the prefix\n" - "\t-e or --entrypoint entry point name, followed by the name\n" + "\t-e or --entrypoint entry point name, followed by the name (_dat will be appended)\n" "\t-r or --revision Specify a version\n" + , argv[0]); #ifdef CAN_GENERATE_OBJECTS + fprintf(stderr, "\t-o or --object write a .obj file instead of .c\n" + "\t-m or --match-arch file.o match the architecture (CPU, 32/64 bits) of the specified .o\n" + "\t ELF format defaults to i386. Windows defaults to the native platform.\n"); #endif - "\t-f or --filename Specify an alternate base filename. (default: symbolname_typ)\n" - , argv[0]); fprintf(stderr, + "\t-f or --filename Specify an alternate base filename. (default: symbolname_typ)\n" "\t-a or --assembly Create assembly file. (possible values are: "); - fprintf(stderr, "%s", assemblyHeader[0].name); - for (idx = 1; idx < (int32_t)(sizeof(assemblyHeader)/sizeof(assemblyHeader[0])); idx++) { - fprintf(stderr, ", %s", assemblyHeader[idx].name); - } - fprintf(stderr, - ")\n"); + printAssemblyHeadersToStdErr(); } else { const char *message, *filename; - void (*writeCode)(const char *, const char *); + /* TODO: remove void (*writeCode)(const char *, const char *); */ if(options[kOptAssembly].doesOccur) { message="generating assembly code for %s\n"; - writeCode=&writeAssemblyCode; - for (idx = 0; idx < (int32_t)(sizeof(assemblyHeader)/sizeof(assemblyHeader[0])); idx++) { - if (uprv_strcmp(options[kOptAssembly].value, assemblyHeader[idx].name) == 0) { - assemblyHeaderIndex = idx; - break; - } - } - if (assemblyHeaderIndex < 0) { + writeCode = CALL_WRITEASSEMBLY; + /* TODO: remove writeCode=&writeAssemblyCode; */ + + if (!checkAssemblyHeaderName(options[kOptAssembly].value)) { fprintf(stderr, "Assembly type \"%s\" is unknown.\n", options[kOptAssembly].value); return -1; @@ -283,506 +147,51 @@ main(int argc, char* argv[]) { #ifdef CAN_GENERATE_OBJECTS else if(options[kOptObject].doesOccur) { message="generating object code for %s\n"; - writeCode=&writeObjectCode; + writeCode = CALL_WRITEOBJECT; + /* TODO: remove writeCode=&writeObjectCode; */ } #endif else { message="generating C code for %s\n"; - writeCode=&writeCCode; + writeCode = CALL_WRITECCODE; + /* TODO: remove writeCode=&writeCCode; */ } while(--argc) { filename=getLongPathname(argv[argc]); if (verbose) { fprintf(stdout, message, filename); } - column=MAX_COLUMN; - writeCode(filename, options[kOptDestDir].value); - } - } - - return 0; -} - -static void -writeAssemblyCode(const char *filename, const char *destdir) { - char entry[64]; - uint32_t buffer[1024]; - char *bufferStr = (char *)buffer; - FileStream *in, *out; - size_t i, length; - - in=T_FileStream_open(filename, "rb"); - if(in==NULL) { - fprintf(stderr, "genccode: unable to open input file %s\n", filename); - exit(U_FILE_ACCESS_ERROR); - } - - getOutFilename(filename, destdir, bufferStr, entry, ".s"); - out=T_FileStream_open(bufferStr, "w"); - if(out==NULL) { - fprintf(stderr, "genccode: unable to open output file %s\n", bufferStr); - exit(U_FILE_ACCESS_ERROR); - } - - if(options[kOptEntryPoint].doesOccur) { - uprv_strcpy(entry, options[kOptEntryPoint].value); - uprv_strcat(entry, "_dat"); - } - - /* turn dashes or dots in the entry name into underscores */ - length=uprv_strlen(entry); - for(i=0; i= 0 ; i--) + case CALL_WRITEOBJECT: + writeObjectCode(filename, options[kOptDestDir].value, + options[kOptEntryPoint].doesOccur ? options[kOptEntryPoint].value : NULL, + options[kOptMatchArch].doesOccur ? options[kOptMatchArch].value : NULL, + options[kOptFilename].doesOccur ? options[kOptFilename].value : NULL, + NULL); + break; #endif - { - uint8_t value = ptrIdx[i]; - if (value || seenNonZero) { - *(s++)=hexToStr[value>>4]; - *(s++)=hexToStr[value&0xF]; - seenNonZero = 1; + default: + /* Should never occur. */ + break; } + /* TODO: remove writeCode(filename, options[kOptDestDir].value); */ } } - *(s++)=0; - T_FileStream_writeLine(out, bitFieldStr); -} - -static void -write8(FileStream *out, uint8_t byte) { - char s[4]; - int i=0; - - /* convert the byte value to a string */ - if(byte>=100) { - s[i++]=(char)('0'+byte/100); - byte%=100; - } - if(i>0 || byte>=10) { - s[i++]=(char)('0'+byte/10); - byte%=10; - } - s[i++]=(char)('0'+byte); - s[i]=0; - - /* write the value, possibly with comma and newline */ - if(column==MAX_COLUMN) { - /* first byte */ - column=1; - } else if(column<16) { - T_FileStream_writeLine(out, ","); - ++column; - } else { - T_FileStream_writeLine(out, ",\n"); - column=1; - } - T_FileStream_writeLine(out, s); -} - -#ifdef OS400 -static void -write8str(FileStream *out, uint8_t byte) { - char s[8]; - - if (byte > 7) - sprintf(s, "\\x%X", byte); - else - sprintf(s, "\\%X", byte); - - /* write the value, possibly with comma and newline */ - if(column==MAX_COLUMN) { - /* first byte */ - column=1; - T_FileStream_writeLine(out, "\""); - } else if(column<24) { - ++column; - } else { - T_FileStream_writeLine(out, "\"\n\""); - column=1; - } - T_FileStream_writeLine(out, s); + return 0; } -#endif -