185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/******************************************************************************
259d709d503bab6e2b61931737e662dd293b40578ccornelius *   Copyright (C) 2009-2013, International Business Machines
385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *   Corporation and others.  All Rights Reserved.
485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *******************************************************************************
585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */
685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/utypes.h"
785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
8103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_HAS_WIN32_API
985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   define VC_EXTRALEAN
1085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   define WIN32_LEAN_AND_MEAN
1185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   define NOUSER
1285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   define NOSERVICE
1385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   define NOIME
1485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   define NOMCX
1585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include <windows.h>
1685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include <time.h>
1785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   ifdef __GNUC__
1885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#       define WINDOWS_WITH_GNUC
1985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   endif
2085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
2185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
2259d709d503bab6e2b61931737e662dd293b40578ccornelius#if U_PLATFORM_IS_LINUX_BASED && U_HAVE_ELF_H
2385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   define U_ELF
2485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
2585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
2685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef U_ELF
2785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   include <elf.h>
2885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   if defined(ELFCLASS64)
2985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#       define U_ELF64
3085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   endif
3185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* Old elf.h headers may not have EM_X86_64, or have EM_X8664 instead. */
3285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   ifndef EM_X86_64
3385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#       define EM_X86_64 62
3485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   endif
3585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   define ICU_ENTRY_OFFSET 0
3685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
3785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
3885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include <stdio.h>
3985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include <stdlib.h>
4085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/putil.h"
4185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "cmemory.h"
4285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "cstring.h"
4385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "filestrm.h"
4485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "toolutil.h"
4585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/uclean.h"
4685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "uoptions.h"
4785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "pkg_genc.h"
4885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
4985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#define MAX_COLUMN ((uint32_t)(0xFFFFFFFFU))
5085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
5185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#define HEX_0X 0 /*  0x1234 */
5285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#define HEX_0H 1 /*  01234h */
5385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
5485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* prototypes --------------------------------------------------------------- */
5585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
5685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HogetOutFilename(const char *inFilename, const char *destdir, char *outFilename, char *entryName, const char *newSuffix, const char *optFilename);
5785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
5885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic uint32_t
5985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Howrite8(FileStream *out, uint8_t byte, uint32_t column);
6085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
6185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic uint32_t
6285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Howrite32(FileStream *out, uint32_t byte, uint32_t column);
6385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
64103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_OS400
6585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic uint32_t
6685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Howrite8str(FileStream *out, uint8_t byte, uint32_t column);
6785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
6885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* -------------------------------------------------------------------------- */
6985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
7085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/*
7185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoCreating Template Files for New Platforms
7285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
7385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoLet the cc compiler help you get started.
7485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoCompile this program
7585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const unsigned int x[5] = {1, 2, 0xdeadbeef, 0xffffffff, 16};
7685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Howith the -S option to produce assembly output.
7785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
7885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoFor example, this will generate array.s:
7985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hogcc -S array.c
8085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
8185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoThis will produce a .s file that may look like this:
8285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
8385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .file   "array.c"
8485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .version        "01.01"
8585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hogcc2_compiled.:
8685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .globl x
8785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .section        .rodata
8885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .align 4
8985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .type    x,@object
9085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .size    x,20
9185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hox:
9285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .long   1
9385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .long   2
9485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .long   -559038737
9585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .long   -1
9685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .long   16
9785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    .ident  "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-85)"
9885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
9985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Howhich gives a starting point that will compile, and can be transformed
10085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoto become the template, generally with some consulting of as docs and
10185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hosome experimentation.
10285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
10385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoIf you want ICU to automatically use this assembly, you should
10485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hospecify "GENCCODE_ASSEMBLY=-a name" in the specific config/mh-* file,
10585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Howhere the name is the compiler or platform that you used in this
10685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoassemblyHeader data structure.
10785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*/
10885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const struct AssemblyType {
10985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const char *name;
11085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const char *header;
11185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const char *beginLine;
11285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const char *footer;
11385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int8_t      hexType; /* HEX_0X or HEX_0h */
11485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} assemblyHeader[] = {
11559d709d503bab6e2b61931737e662dd293b40578ccornelius    // For gcc assemblers, the meaning of .align changes depending on the
11659d709d503bab6e2b61931737e662dd293b40578ccornelius    // hardware, so we use .balign 16 which always means 16 bytes.
11759d709d503bab6e2b61931737e662dd293b40578ccornelius    // https://sourceware.org/binutils/docs/as/Pseudo-Ops.html
11885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    {"gcc",
11985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ".globl %s\n"
12027f654740f2a26ad62a5c155af9199af9e69b889claireho        "\t.section .note.GNU-stack,\"\",%%progbits\n"
12185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.section .rodata\n"
12259d709d503bab6e2b61931737e662dd293b40578ccornelius        "\t.balign 16\n"
12327f654740f2a26ad62a5c155af9199af9e69b889claireho        "\t.type %s,%%object\n"
12485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "%s:\n\n",
12585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
12685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ".long ","",HEX_0X
12785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    },
12885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    {"gcc-darwin",
12985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /*"\t.section __TEXT,__text,regular,pure_instructions\n"
13085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32\n"*/
13185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ".globl _%s\n"
13285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.data\n"
13385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.const\n"
13459d709d503bab6e2b61931737e662dd293b40578ccornelius        "\t.balign 16\n"
13585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "_%s:\n\n",
13685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
13785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ".long ","",HEX_0X
13885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    },
13985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    {"gcc-cygwin",
1408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        ".globl _%s\n"
14185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.section .rodata\n"
14259d709d503bab6e2b61931737e662dd293b40578ccornelius        "\t.balign 16\n"
1438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        "_%s:\n\n",
1448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius
1458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        ".long ","",HEX_0X
1468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    },
1478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    {"gcc-mingw64",
1488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        ".globl %s\n"
1498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        "\t.section .rodata\n"
15059d709d503bab6e2b61931737e662dd293b40578ccornelius        "\t.balign 16\n"
1518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        "%s:\n\n",
15285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
15385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ".long ","",HEX_0X
15485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    },
15559d709d503bab6e2b61931737e662dd293b40578ccornelius// 16 bytes alignment.
15659d709d503bab6e2b61931737e662dd293b40578ccornelius// http://docs.oracle.com/cd/E19641-01/802-1947/802-1947.pdf
15785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    {"sun",
15885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.section \".rodata\"\n"
15959d709d503bab6e2b61931737e662dd293b40578ccornelius        "\t.align   16\n"
16085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ".globl     %s\n"
16185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "%s:\n",
16285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
16385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ".word ","",HEX_0X
16485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    },
16559d709d503bab6e2b61931737e662dd293b40578ccornelius// 16 bytes alignment for sun-x86.
16659d709d503bab6e2b61931737e662dd293b40578ccornelius// http://docs.oracle.com/cd/E19963-01/html/821-1608/eoiyg.html
16785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    {"sun-x86",
16885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "Drodata.rodata:\n"
16985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.type   Drodata.rodata,@object\n"
17085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.size   Drodata.rodata,0\n"
17185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.globl  %s\n"
17259d709d503bab6e2b61931737e662dd293b40578ccornelius        "\t.align  16\n"
17385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "%s:\n",
17485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
17585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ".4byte ","",HEX_0X
17685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    },
17759d709d503bab6e2b61931737e662dd293b40578ccornelius// 1<<4 bit alignment for aix.
17859d709d503bab6e2b61931737e662dd293b40578ccornelius// http://pic.dhe.ibm.com/infocenter/aix/v6r1/index.jsp?topic=%2Fcom.ibm.aix.aixassem%2Fdoc%2Falangref%2Fidalangref_csect_pseudoop.htm
17985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    {"xlc",
18085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ".globl %s{RO}\n"
18185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.toc\n"
18285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "%s:\n"
18385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.csect %s{RO}, 4\n",
18485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
18585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ".long ","",HEX_0X
18685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    },
18785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    {"aCC-ia64",
18885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.file   \"%s.s\"\n"
18985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.type   %s,@object\n"
19085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.global %s\n"
19185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.secalias .abe$0.rodata, \".rodata\"\n"
19285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.section .abe$0.rodata = \"a\", \"progbits\"\n"
19385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.align  16\n"
19485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "%s::\t",
19585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
19685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "data4 ","",HEX_0X
19785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    },
19885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    {"aCC-parisc",
19985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.SPACE  $TEXT$\n"
20085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.SUBSPA $LIT$\n"
20185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "%s\n"
20285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.EXPORT %s\n"
20385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "\t.ALIGN  16\n",
20485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
20585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ".WORD ","",HEX_0X
20685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    },
20759d709d503bab6e2b61931737e662dd293b40578ccornelius// align 16 bytes
20859d709d503bab6e2b61931737e662dd293b40578ccornelius//  http://msdn.microsoft.com/en-us/library/dwa9fwef.aspx
20985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    { "masm",
21085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      "\tTITLE %s\n"
21185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      "; generated by genccode\n"
21285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      ".386\n"
21385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      ".model flat\n"
21485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      "\tPUBLIC _%s\n"
21585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      "ICUDATA_%s\tSEGMENT READONLY PARA PUBLIC FLAT 'DATA'\n"
21685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      "\tALIGN 16\n"
21785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      "_%s\tLABEL DWORD\n",
21885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      "\tDWORD ","\nICUDATA_%s\tENDS\n\tEND\n",HEX_0H
21985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
22085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
22185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
22285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic int32_t assemblyHeaderIndex = -1;
22385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic int32_t hexType = HEX_0X;
22485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
22585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_CAPI UBool U_EXPORT2
22685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HocheckAssemblyHeaderName(const char* optAssembly) {
22785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t idx;
22885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    assemblyHeaderIndex = -1;
22985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for (idx = 0; idx < (int32_t)(sizeof(assemblyHeader)/sizeof(assemblyHeader[0])); idx++) {
23085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (uprv_strcmp(optAssembly, assemblyHeader[idx].name) == 0) {
23185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            assemblyHeaderIndex = idx;
23285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            hexType = assemblyHeader[idx].hexType; /* set the hex type */
23385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return TRUE;
23485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
23585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
23685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
23785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return FALSE;
23885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
23985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
24085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
24185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_CAPI void U_EXPORT2
24285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoprintAssemblyHeadersToStdErr(void) {
24385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t idx;
24485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fprintf(stderr, "%s", assemblyHeader[0].name);
24585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for (idx = 1; idx < (int32_t)(sizeof(assemblyHeader)/sizeof(assemblyHeader[0])); idx++) {
24685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, ", %s", assemblyHeader[idx].name);
24785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
24885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fprintf(stderr,
24985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ")\n");
25085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
25185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
25285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_CAPI void U_EXPORT2
25385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HowriteAssemblyCode(const char *filename, const char *destdir, const char *optEntryPoint, const char *optFilename, char *outFilePath) {
25485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t column = MAX_COLUMN;
25585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char entry[64];
25685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t buffer[1024];
25785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char *bufferStr = (char *)buffer;
25885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    FileStream *in, *out;
25985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    size_t i, length;
26085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
26185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    in=T_FileStream_open(filename, "rb");
26285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(in==NULL) {
26385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: unable to open input file %s\n", filename);
26485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
26585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
26685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
26785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    getOutFilename(filename, destdir, bufferStr, entry, ".s", optFilename);
26885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    out=T_FileStream_open(bufferStr, "w");
26985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(out==NULL) {
27085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: unable to open output file %s\n", bufferStr);
27185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
27285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
27385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
27485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (outFilePath != NULL) {
27585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_strcpy(outFilePath, bufferStr);
27685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
27785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
27885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef WINDOWS_WITH_GNUC
27985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* Need to fix the file seperator character when using MinGW. */
28085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    swapFileSepChar(outFilePath, U_FILE_SEP_CHAR, '/');
28185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
28285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
28385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(optEntryPoint != NULL) {
28485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_strcpy(entry, optEntryPoint);
28585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_strcat(entry, "_dat");
28685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
28785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
28885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* turn dashes or dots in the entry name into underscores */
28985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    length=uprv_strlen(entry);
29085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=0; i<length; ++i) {
29185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(entry[i]=='-' || entry[i]=='.') {
29285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            entry[i]='_';
29385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
29485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
29585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
29685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    sprintf(bufferStr, assemblyHeader[assemblyHeaderIndex].header,
29785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        entry, entry, entry, entry,
29885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        entry, entry, entry, entry);
29985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_writeLine(out, bufferStr);
30085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_writeLine(out, assemblyHeader[assemblyHeaderIndex].beginLine);
30185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
30285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(;;) {
30385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        length=T_FileStream_read(in, buffer, sizeof(buffer));
30485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(length==0) {
30585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
30685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
30785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (length != sizeof(buffer)) {
30885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* pad with extra 0's when at the end of the file */
30985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            for(i=0; i < (length % sizeof(uint32_t)); ++i) {
31085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                buffer[length+i] = 0;
31185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
31285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
31385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        for(i=0; i<(length/sizeof(buffer[0])); i++) {
31485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            column = write32(out, buffer[i], column);
31585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
31685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
31785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
31885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_writeLine(out, "\n");
31985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
32085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    sprintf(bufferStr, assemblyHeader[assemblyHeaderIndex].footer,
32185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        entry, entry, entry, entry,
32285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        entry, entry, entry, entry);
32385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_writeLine(out, bufferStr);
32485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
32585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(T_FileStream_error(in)) {
32685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: file read error while generating from file %s\n", filename);
32785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
32885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
32985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
33085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(T_FileStream_error(out)) {
33185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: file write error while generating from file %s\n", filename);
33285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
33385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
33485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
33585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_close(out);
33685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_close(in);
33785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
33885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
33985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_CAPI void U_EXPORT2
34085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HowriteCCode(const char *filename, const char *destdir, const char *optName, const char *optFilename, char *outFilePath) {
34185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint32_t column = MAX_COLUMN;
34285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char buffer[4096], entry[64];
34385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    FileStream *in, *out;
34485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    size_t i, length;
34585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
34685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    in=T_FileStream_open(filename, "rb");
34785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(in==NULL) {
34885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: unable to open input file %s\n", filename);
34985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
35085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
35185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
35285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(optName != NULL) { /* prepend  'icudt28_' */
35385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      strcpy(entry, optName);
35485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      strcat(entry, "_");
35585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
35685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      entry[0] = 0;
35785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
35885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
35985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    getOutFilename(filename, destdir, buffer, entry+uprv_strlen(entry), ".c", optFilename);
36085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (outFilePath != NULL) {
36185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_strcpy(outFilePath, buffer);
36285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
36385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    out=T_FileStream_open(buffer, "w");
36485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(out==NULL) {
36585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: unable to open output file %s\n", buffer);
36685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
36785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
36885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
36985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* turn dashes or dots in the entry name into underscores */
37085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    length=uprv_strlen(entry);
37185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=0; i<length; ++i) {
37285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(entry[i]=='-' || entry[i]=='.') {
37385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            entry[i]='_';
37485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
37585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
37685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
377103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_OS400
37885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*
37985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    TODO: Fix this once the compiler implements this feature. Keep in sync with udatamem.c
38085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
38185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    This is here because this platform can't currently put
38285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const data into the read-only pages of an object or
38385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    shared library (service program). Only strings are allowed in read-only
38485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    pages, so we use char * strings to store the data.
38585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
38685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    In order to prevent the beginning of the data from ever matching the
38785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    magic numbers we must still use the initial double.
38885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    [grhoten 4/24/2003]
38985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    */
39085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    sprintf(buffer,
391103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        "#ifndef IN_GENERATED_CCODE\n"
392103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        "#define IN_GENERATED_CCODE\n"
39385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "#define U_DISABLE_RENAMING 1\n"
39485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "#include \"unicode/umachine.h\"\n"
395103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        "#endif\n"
39685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "U_CDECL_BEGIN\n"
39785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "const struct {\n"
39885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "    double bogus;\n"
39985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "    const char *bytes; \n"
40085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "} %s={ 0.0, \n",
40185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        entry);
40285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_writeLine(out, buffer);
40385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
40485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(;;) {
40585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        length=T_FileStream_read(in, buffer, sizeof(buffer));
40685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(length==0) {
40785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
40885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
40985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        for(i=0; i<length; ++i) {
41085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            column = write8str(out, (uint8_t)buffer[i], column);
41185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
41285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
41385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
41485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_writeLine(out, "\"\n};\nU_CDECL_END\n");
41585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else
41685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* Function renaming shouldn't be done in data */
41785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    sprintf(buffer,
418103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        "#ifndef IN_GENERATED_CCODE\n"
419103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        "#define IN_GENERATED_CCODE\n"
42085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "#define U_DISABLE_RENAMING 1\n"
42185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "#include \"unicode/umachine.h\"\n"
422103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        "#endif\n"
42385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "U_CDECL_BEGIN\n"
42485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "const struct {\n"
42585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "    double bogus;\n"
42685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "    uint8_t bytes[%ld]; \n"
42785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        "} %s={ 0.0, {\n",
42885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (long)T_FileStream_size(in), entry);
42985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_writeLine(out, buffer);
43085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
43185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(;;) {
43285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        length=T_FileStream_read(in, buffer, sizeof(buffer));
43385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(length==0) {
43485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
43585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
43685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        for(i=0; i<length; ++i) {
43785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            column = write8(out, (uint8_t)buffer[i], column);
43885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
43985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
44085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
44185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_writeLine(out, "\n}\n};\nU_CDECL_END\n");
44285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
44385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
44485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(T_FileStream_error(in)) {
44585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: file read error while generating from file %s\n", filename);
44685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
44785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
44885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
44985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(T_FileStream_error(out)) {
45085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: file write error while generating from file %s\n", filename);
45185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
45285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
45385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
45485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_close(out);
45585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_close(in);
45685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
45785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
45885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic uint32_t
45985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Howrite32(FileStream *out, uint32_t bitField, uint32_t column) {
46085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t i;
46185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char bitFieldStr[64]; /* This is more bits than needed for a 32-bit number */
46285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char *s = bitFieldStr;
46385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint8_t *ptrIdx = (uint8_t *)&bitField;
46485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const char hexToStr[16] = {
46585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        '0','1','2','3',
46685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        '4','5','6','7',
46785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        '8','9','A','B',
46885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        'C','D','E','F'
46985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
47085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
47185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* write the value, possibly with comma and newline */
47285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(column==MAX_COLUMN) {
47385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* first byte */
47485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        column=1;
47585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else if(column<32) {
47685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *(s++)=',';
47785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ++column;
47885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
47985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *(s++)='\n';
48085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_strcpy(s, assemblyHeader[assemblyHeaderIndex].beginLine);
48185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        s+=uprv_strlen(s);
48285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        column=1;
48385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
48485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
48585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (bitField < 10) {
48685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* It's a small number. Don't waste the space for 0x */
48785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *(s++)=hexToStr[bitField];
48885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
48985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    else {
49085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        int seenNonZero = 0; /* This is used to remove leading zeros */
49185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
49285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(hexType==HEX_0X) {
49385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         *(s++)='0';
49485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         *(s++)='x';
49585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else if(hexType==HEX_0H) {
49685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         *(s++)='0';
49785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
49885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
49985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* This creates a 32-bit field */
50085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if U_IS_BIG_ENDIAN
50185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        for (i = 0; i < sizeof(uint32_t); i++)
50285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else
50385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        for (i = sizeof(uint32_t)-1; i >= 0 ; i--)
50485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
50585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {
50685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            uint8_t value = ptrIdx[i];
50785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (value || seenNonZero) {
50885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                *(s++)=hexToStr[value>>4];
50985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                *(s++)=hexToStr[value&0xF];
51085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                seenNonZero = 1;
51185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
51285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
51385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(hexType==HEX_0H) {
51485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         *(s++)='h';
51585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
51685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
51785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
51885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    *(s++)=0;
51985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_writeLine(out, bitFieldStr);
52085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return column;
52185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
52285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
52385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic uint32_t
52485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Howrite8(FileStream *out, uint8_t byte, uint32_t column) {
52585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char s[4];
52685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int i=0;
52785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
52885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* convert the byte value to a string */
52985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(byte>=100) {
53085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        s[i++]=(char)('0'+byte/100);
53185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        byte%=100;
53285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
53385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(i>0 || byte>=10) {
53485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        s[i++]=(char)('0'+byte/10);
53585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        byte%=10;
53685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
53785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    s[i++]=(char)('0'+byte);
53885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    s[i]=0;
53985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
54085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* write the value, possibly with comma and newline */
54185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(column==MAX_COLUMN) {
54285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* first byte */
54385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        column=1;
54485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else if(column<16) {
54585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        T_FileStream_writeLine(out, ",");
54685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ++column;
54785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
54885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        T_FileStream_writeLine(out, ",\n");
54985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        column=1;
55085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
55185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_writeLine(out, s);
55285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return column;
55385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
55485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
555103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_OS400
55685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic uint32_t
55785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Howrite8str(FileStream *out, uint8_t byte, uint32_t column) {
55885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char s[8];
55985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
56085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (byte > 7)
56185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        sprintf(s, "\\x%X", byte);
56285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    else
56385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        sprintf(s, "\\%X", byte);
56485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
56585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* write the value, possibly with comma and newline */
56685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(column==MAX_COLUMN) {
56785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* first byte */
56885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        column=1;
56985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        T_FileStream_writeLine(out, "\"");
57085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else if(column<24) {
57185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ++column;
57285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
57385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        T_FileStream_writeLine(out, "\"\n\"");
57485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        column=1;
57585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
57685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_writeLine(out, s);
57785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return column;
57885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
57985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
58085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
58185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
58285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HogetOutFilename(const char *inFilename, const char *destdir, char *outFilename, char *entryName, const char *newSuffix, const char *optFilename) {
58385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const char *basename=findBasename(inFilename), *suffix=uprv_strrchr(basename, '.');
58485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
58585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* copy path */
58685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(destdir!=NULL && *destdir!=0) {
58785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        do {
58885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            *outFilename++=*destdir++;
58985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } while(*destdir!=0);
59085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(*(outFilename-1)!=U_FILE_SEP_CHAR) {
59185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            *outFilename++=U_FILE_SEP_CHAR;
59285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
59385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        inFilename=basename;
59485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
59585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        while(inFilename<basename) {
59685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            *outFilename++=*inFilename++;
59785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
59885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
59985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
60085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(suffix==NULL) {
60185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* the filename does not have a suffix */
60285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_strcpy(entryName, inFilename);
60385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(optFilename != NULL) {
60485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho          uprv_strcpy(outFilename, optFilename);
60585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
60685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho          uprv_strcpy(outFilename, inFilename);
60785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
60885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_strcat(outFilename, newSuffix);
60985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
61085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        char *saveOutFilename = outFilename;
61185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* copy basename */
61285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        while(inFilename<suffix) {
61385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if(*inFilename=='-') {
61485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                /* iSeries cannot have '-' in the .o objects. */
61585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                *outFilename++=*entryName++='_';
61685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                inFilename++;
61785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
61885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            else {
61985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                *outFilename++=*entryName++=*inFilename++;
62085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
62185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
62285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
62385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* replace '.' by '_' */
62485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *outFilename++=*entryName++='_';
62585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ++inFilename;
62685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
62785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* copy suffix */
62885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        while(*inFilename!=0) {
62985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            *outFilename++=*entryName++=*inFilename++;
63085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
63185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
63285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *entryName=0;
63385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
63485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(optFilename != NULL) {
63585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            uprv_strcpy(saveOutFilename, optFilename);
63685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            uprv_strcat(saveOutFilename, newSuffix);
63785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
63885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* add ".c" */
63985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            uprv_strcpy(outFilename, newSuffix);
64085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
64185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
64285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
64385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
64485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef CAN_GENERATE_OBJECTS
64585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void
64685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HogetArchitecture(uint16_t *pCPU, uint16_t *pBits, UBool *pIsBigEndian, const char *optMatchArch) {
64727f654740f2a26ad62a5c155af9199af9e69b889claireho    union {
64827f654740f2a26ad62a5c155af9199af9e69b889claireho        char        bytes[2048];
64927f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef U_ELF
65027f654740f2a26ad62a5c155af9199af9e69b889claireho        Elf32_Ehdr  header32;
65127f654740f2a26ad62a5c155af9199af9e69b889claireho        /* Elf32_Ehdr and ELF64_Ehdr are identical for the necessary fields. */
652103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM_HAS_WIN32_API
65327f654740f2a26ad62a5c155af9199af9e69b889claireho        IMAGE_FILE_HEADER header;
65427f654740f2a26ad62a5c155af9199af9e69b889claireho#endif
65527f654740f2a26ad62a5c155af9199af9e69b889claireho    } buffer;
65627f654740f2a26ad62a5c155af9199af9e69b889claireho
65785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const char *filename;
65885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    FileStream *in;
65985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t length;
66085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
66185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef U_ELF
66227f654740f2a26ad62a5c155af9199af9e69b889claireho
663103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM_HAS_WIN32_API
66485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const IMAGE_FILE_HEADER *pHeader;
66585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else
66685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   error "Unknown platform for CAN_GENERATE_OBJECTS."
66785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
66885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
66985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(optMatchArch != NULL) {
67085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        filename=optMatchArch;
67185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
67285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* set defaults */
67385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef U_ELF
67485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* set EM_386 because elf.h does not provide better defaults */
67585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *pCPU=EM_386;
67685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *pBits=32;
67785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *pIsBigEndian=(UBool)(U_IS_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB);
678103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM_HAS_WIN32_API
67985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* _M_IA64 should be defined in windows.h */
68085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   if defined(_M_IA64)
68185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *pCPU=IMAGE_FILE_MACHINE_IA64;
68285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   elif defined(_M_AMD64)
68385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *pCPU=IMAGE_FILE_MACHINE_AMD64;
68485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   else
68585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *pCPU=IMAGE_FILE_MACHINE_I386;
68685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   endif
68785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *pBits= *pCPU==IMAGE_FILE_MACHINE_I386 ? 32 : 64;
68885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *pIsBigEndian=FALSE;
68985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else
69085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   error "Unknown platform for CAN_GENERATE_OBJECTS."
69185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
69285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
69385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
69485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
69585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    in=T_FileStream_open(filename, "rb");
69685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(in==NULL) {
69785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: unable to open match-arch file %s\n", filename);
69885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
69985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
70027f654740f2a26ad62a5c155af9199af9e69b889claireho    length=T_FileStream_read(in, buffer.bytes, sizeof(buffer.bytes));
70185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
70285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef U_ELF
70385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(length<sizeof(Elf32_Ehdr)) {
70485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: match-arch file %s is too short\n", filename);
70585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_UNSUPPORTED_ERROR);
70685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
70785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(
70827f654740f2a26ad62a5c155af9199af9e69b889claireho        buffer.header32.e_ident[0]!=ELFMAG0 ||
70927f654740f2a26ad62a5c155af9199af9e69b889claireho        buffer.header32.e_ident[1]!=ELFMAG1 ||
71027f654740f2a26ad62a5c155af9199af9e69b889claireho        buffer.header32.e_ident[2]!=ELFMAG2 ||
71127f654740f2a26ad62a5c155af9199af9e69b889claireho        buffer.header32.e_ident[3]!=ELFMAG3 ||
71227f654740f2a26ad62a5c155af9199af9e69b889claireho        buffer.header32.e_ident[EI_CLASS]<ELFCLASS32 || buffer.header32.e_ident[EI_CLASS]>ELFCLASS64
71385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    ) {
71485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: match-arch file %s is not an ELF object file, or not supported\n", filename);
71585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_UNSUPPORTED_ERROR);
71685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
71785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
71827f654740f2a26ad62a5c155af9199af9e69b889claireho    *pBits= buffer.header32.e_ident[EI_CLASS]==ELFCLASS32 ? 32 : 64; /* only 32 or 64: see check above */
71985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef U_ELF64
72085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(*pBits!=32 && *pBits!=64) {
72185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: currently only supports 32-bit and 64-bit ELF format\n");
72285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_UNSUPPORTED_ERROR);
72385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
72485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else
72585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(*pBits!=32) {
72685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: built with elf.h missing 64-bit definitions\n");
72785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_UNSUPPORTED_ERROR);
72885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
72985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
73085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
73127f654740f2a26ad62a5c155af9199af9e69b889claireho    *pIsBigEndian=(UBool)(buffer.header32.e_ident[EI_DATA]==ELFDATA2MSB);
73285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(*pIsBigEndian!=U_IS_BIG_ENDIAN) {
73385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: currently only same-endianness ELF formats are supported\n");
73485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_UNSUPPORTED_ERROR);
73585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
73685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* TODO: Support byte swapping */
73785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
73827f654740f2a26ad62a5c155af9199af9e69b889claireho    *pCPU=buffer.header32.e_machine;
739103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM_HAS_WIN32_API
74085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(length<sizeof(IMAGE_FILE_HEADER)) {
74185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: match-arch file %s is too short\n", filename);
74285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_UNSUPPORTED_ERROR);
74385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
74427f654740f2a26ad62a5c155af9199af9e69b889claireho    /* TODO: Use buffer.header.  Keep aliasing legal.  */
74527f654740f2a26ad62a5c155af9199af9e69b889claireho    pHeader=(const IMAGE_FILE_HEADER *)buffer.bytes;
74685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    *pCPU=pHeader->Machine;
74785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*
74885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * The number of bits is implicit with the Machine value.
74985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * *pBits is ignored in the calling code, so this need not be precise.
75085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     */
75185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    *pBits= *pCPU==IMAGE_FILE_MACHINE_I386 ? 32 : 64;
75285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* Windows always runs on little-endian CPUs. */
75385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    *pIsBigEndian=FALSE;
75485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else
75585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   error "Unknown platform for CAN_GENERATE_OBJECTS."
75685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
75785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
75885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_close(in);
75985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
76085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
76185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_CAPI void U_EXPORT2
76285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HowriteObjectCode(const char *filename, const char *destdir, const char *optEntryPoint, const char *optMatchArch, const char *optFilename, char *outFilePath) {
76385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* common variables */
76485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char buffer[4096], entry[40]={ 0 };
76585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    FileStream *in, *out;
76685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const char *newSuffix;
76785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t i, entryLength, length, size, entryOffset=0, entryLengthOffset=0;
76885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
76985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uint16_t cpu, bits;
77085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UBool makeBigEndian;
77185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
77285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* platform-specific variables and initialization code */
77385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef U_ELF
77485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* 32-bit Elf file header */
77585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static Elf32_Ehdr header32={
77685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {
77785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* e_ident[] */
77885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
77985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ELFCLASS32,
78085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            U_IS_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB,
78185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            EV_CURRENT /* EI_VERSION */
78285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        },
78385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ET_REL,
78485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        EM_386,
78585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        EV_CURRENT, /* e_version */
78685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0, /* e_entry */
78785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0, /* e_phoff */
78885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (Elf32_Off)sizeof(Elf32_Ehdr), /* e_shoff */
78985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0, /* e_flags */
79085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (Elf32_Half)sizeof(Elf32_Ehdr), /* eh_size */
79185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0, /* e_phentsize */
79285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0, /* e_phnum */
79385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (Elf32_Half)sizeof(Elf32_Shdr), /* e_shentsize */
79485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        5, /* e_shnum */
79585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        2 /* e_shstrndx */
79685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
79785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
79885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* 32-bit Elf section header table */
79985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static Elf32_Shdr sectionHeaders32[5]={
80085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* SHN_UNDEF */
80185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0
80285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        },
80385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* .symtab */
80485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            1, /* sh_name */
80585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            SHT_SYMTAB,
80685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_flags */
80785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_addr */
80885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf32_Off)(sizeof(header32)+sizeof(sectionHeaders32)), /* sh_offset */
80985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf32_Word)(2*sizeof(Elf32_Sym)), /* sh_size */
81085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            3, /* sh_link=sect hdr index of .strtab */
81185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            1, /* sh_info=One greater than the symbol table index of the last
81285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                * local symbol (with STB_LOCAL). */
81385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            4, /* sh_addralign */
81485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf32_Word)(sizeof(Elf32_Sym)) /* sh_entsize */
81585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        },
81685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* .shstrtab */
81785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            9, /* sh_name */
81885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            SHT_STRTAB,
81985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_flags */
82085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_addr */
82185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf32_Off)(sizeof(header32)+sizeof(sectionHeaders32)+2*sizeof(Elf32_Sym)), /* sh_offset */
82285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            40, /* sh_size */
82385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_link */
82485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_info */
82585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            1, /* sh_addralign */
82685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0 /* sh_entsize */
82785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        },
82885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* .strtab */
82985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            19, /* sh_name */
83085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            SHT_STRTAB,
83185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_flags */
83285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_addr */
83385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf32_Off)(sizeof(header32)+sizeof(sectionHeaders32)+2*sizeof(Elf32_Sym)+40), /* sh_offset */
83485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf32_Word)sizeof(entry), /* sh_size */
83585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_link */
83685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_info */
83785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            1, /* sh_addralign */
83885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0 /* sh_entsize */
83985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        },
84085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* .rodata */
84185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            27, /* sh_name */
84285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            SHT_PROGBITS,
84385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            SHF_ALLOC, /* sh_flags */
84485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_addr */
84585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf32_Off)(sizeof(header32)+sizeof(sectionHeaders32)+2*sizeof(Elf32_Sym)+40+sizeof(entry)), /* sh_offset */
84685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_size */
84785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_link */
84885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_info */
84985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            16, /* sh_addralign */
85085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0 /* sh_entsize */
85185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
85285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
85385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
85485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* symbol table */
85585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static Elf32_Sym symbols32[2]={
85685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* STN_UNDEF */
85785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0
85885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        },
85985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* data entry point */
86085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            1, /* st_name */
86185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* st_value */
86285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* st_size */
86385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ELF64_ST_INFO(STB_GLOBAL, STT_OBJECT),
86485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* st_other */
86585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            4 /* st_shndx=index of related section table entry */
86685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
86785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
86885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
86985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* section header string table, with decimal string offsets */
87085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const char sectionStrings[40]=
87185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /*  0 */ "\0"
87285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /*  1 */ ".symtab\0"
87385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /*  9 */ ".shstrtab\0"
87485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* 19 */ ".strtab\0"
87585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* 27 */ ".rodata\0"
87685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* 35 */ "\0\0\0\0"; /* contains terminating NUL */
87785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* 40: padded to multiple of 8 bytes */
87885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
87985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*
88085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * Use entry[] for the string table which will contain only the
88185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * entry point name.
88285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * entry[0] must be 0 (NUL)
88385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * The entry point name can be up to 38 characters long (sizeof(entry)-2).
88485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     */
88585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
88685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* 16-align .rodata in the .o file, just in case */
88785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const char padding[16]={ 0 };
88885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t paddingSize;
88985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
89085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef U_ELF64
89185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* 64-bit Elf file header */
89285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static Elf64_Ehdr header64={
89385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {
89485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* e_ident[] */
89585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
89685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ELFCLASS64,
89785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            U_IS_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB,
89885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            EV_CURRENT /* EI_VERSION */
89985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        },
90085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ET_REL,
90185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        EM_X86_64,
90285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        EV_CURRENT, /* e_version */
90385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0, /* e_entry */
90485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0, /* e_phoff */
90585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (Elf64_Off)sizeof(Elf64_Ehdr), /* e_shoff */
90685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0, /* e_flags */
90785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (Elf64_Half)sizeof(Elf64_Ehdr), /* eh_size */
90885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0, /* e_phentsize */
90985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0, /* e_phnum */
91085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        (Elf64_Half)sizeof(Elf64_Shdr), /* e_shentsize */
91185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        5, /* e_shnum */
91285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        2 /* e_shstrndx */
91385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
91485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
91585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* 64-bit Elf section header table */
91685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static Elf64_Shdr sectionHeaders64[5]={
91785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* SHN_UNDEF */
91885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0
91985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        },
92085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* .symtab */
92185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            1, /* sh_name */
92285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            SHT_SYMTAB,
92385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_flags */
92485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_addr */
92585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf64_Off)(sizeof(header64)+sizeof(sectionHeaders64)), /* sh_offset */
92685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf64_Xword)(2*sizeof(Elf64_Sym)), /* sh_size */
92785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            3, /* sh_link=sect hdr index of .strtab */
92885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            1, /* sh_info=One greater than the symbol table index of the last
92985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                * local symbol (with STB_LOCAL). */
93085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            4, /* sh_addralign */
93185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf64_Xword)(sizeof(Elf64_Sym)) /* sh_entsize */
93285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        },
93385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* .shstrtab */
93485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            9, /* sh_name */
93585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            SHT_STRTAB,
93685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_flags */
93785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_addr */
93885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf64_Off)(sizeof(header64)+sizeof(sectionHeaders64)+2*sizeof(Elf64_Sym)), /* sh_offset */
93985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            40, /* sh_size */
94085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_link */
94185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_info */
94285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            1, /* sh_addralign */
94385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0 /* sh_entsize */
94485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        },
94585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* .strtab */
94685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            19, /* sh_name */
94785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            SHT_STRTAB,
94885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_flags */
94985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_addr */
95085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf64_Off)(sizeof(header64)+sizeof(sectionHeaders64)+2*sizeof(Elf64_Sym)+40), /* sh_offset */
95185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf64_Xword)sizeof(entry), /* sh_size */
95285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_link */
95385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_info */
95485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            1, /* sh_addralign */
95585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0 /* sh_entsize */
95685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        },
95785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* .rodata */
95885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            27, /* sh_name */
95985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            SHT_PROGBITS,
96085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            SHF_ALLOC, /* sh_flags */
96185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_addr */
96285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            (Elf64_Off)(sizeof(header64)+sizeof(sectionHeaders64)+2*sizeof(Elf64_Sym)+40+sizeof(entry)), /* sh_offset */
96385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_size */
96485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_link */
96585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* sh_info */
96685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            16, /* sh_addralign */
96785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0 /* sh_entsize */
96885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
96985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
97085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
97185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*
97285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * 64-bit symbol table
97385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * careful: different order of items compared with Elf32_sym!
97485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     */
97585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static Elf64_Sym symbols64[2]={
97685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* STN_UNDEF */
97785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0
97885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        },
97985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { /* data entry point */
98085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            1, /* st_name */
98185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ELF64_ST_INFO(STB_GLOBAL, STT_OBJECT),
98285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* st_other */
98385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            4, /* st_shndx=index of related section table entry */
98485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0, /* st_value */
98585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            0 /* st_size */
98685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
98785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
98885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
98985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif /* U_ELF64 */
99085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
99185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* entry[] have a leading NUL */
99285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    entryOffset=1;
99385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
99485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* in the common code, count entryLength from after the NUL */
99585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    entryLengthOffset=1;
99685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
99785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    newSuffix=".o";
99885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
999103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM_HAS_WIN32_API
100085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    struct {
100185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        IMAGE_FILE_HEADER fileHeader;
100285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        IMAGE_SECTION_HEADER sections[2];
100385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        char linkerOptions[100];
100485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } objHeader;
100585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    IMAGE_SYMBOL symbols[1];
100685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    struct {
100785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        DWORD sizeofLongNames;
100885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        char longNames[100];
100985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } symbolNames;
101085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
101185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*
101285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * entry sometimes have a leading '_'
101385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * overwritten if entryOffset==0 depending on the target platform
101485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * see check for cpu below
101585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     */
101685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    entry[0]='_';
101785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
101885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    newSuffix=".obj";
101985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else
102085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   error "Unknown platform for CAN_GENERATE_OBJECTS."
102185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
102285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
102385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* deal with options, files and the entry point name */
102485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    getArchitecture(&cpu, &bits, &makeBigEndian, optMatchArch);
102554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    printf("genccode: --match-arch cpu=%hu bits=%hu big-endian=%d\n", cpu, bits, makeBigEndian);
1026103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_HAS_WIN32_API
102785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(cpu==IMAGE_FILE_MACHINE_I386) {
102885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        entryOffset=1;
102985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
103085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
103185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
103285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    in=T_FileStream_open(filename, "rb");
103385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(in==NULL) {
103485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: unable to open input file %s\n", filename);
103585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
103685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
103785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    size=T_FileStream_size(in);
103885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
103985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    getOutFilename(filename, destdir, buffer, entry+entryOffset, newSuffix, optFilename);
104085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (outFilePath != NULL) {
104185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_strcpy(outFilePath, buffer);
104285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
104385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
104485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(optEntryPoint != NULL) {
104585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_strcpy(entry+entryOffset, optEntryPoint);
104685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_strcat(entry+entryOffset, "_dat");
104785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
104885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* turn dashes in the entry name into underscores */
104985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    entryLength=(int32_t)uprv_strlen(entry+entryLengthOffset);
105085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(i=0; i<entryLength; ++i) {
105185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(entry[entryLengthOffset+i]=='-') {
105285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            entry[entryLengthOffset+i]='_';
105385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
105485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
105585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
105685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* open the output file */
105785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    out=T_FileStream_open(buffer, "wb");
105885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(out==NULL) {
105985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: unable to open output file %s\n", buffer);
106085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
106185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
106285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
106385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef U_ELF
106485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(bits==32) {
106585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        header32.e_ident[EI_DATA]= makeBigEndian ? ELFDATA2MSB : ELFDATA2LSB;
106685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        header32.e_machine=cpu;
106785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
106885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* 16-align .rodata in the .o file, just in case */
106985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        paddingSize=sectionHeaders32[4].sh_offset & 0xf;
107085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(paddingSize!=0) {
107185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                paddingSize=0x10-paddingSize;
107285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                sectionHeaders32[4].sh_offset+=paddingSize;
107385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
107485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
107585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        sectionHeaders32[4].sh_size=(Elf32_Word)size;
107685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
107785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        symbols32[1].st_size=(Elf32_Word)size;
107885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
107985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* write .o headers */
108085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        T_FileStream_write(out, &header32, (int32_t)sizeof(header32));
108185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        T_FileStream_write(out, sectionHeaders32, (int32_t)sizeof(sectionHeaders32));
108285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        T_FileStream_write(out, symbols32, (int32_t)sizeof(symbols32));
108385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else /* bits==64 */ {
108485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef U_ELF64
108585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        header64.e_ident[EI_DATA]= makeBigEndian ? ELFDATA2MSB : ELFDATA2LSB;
108685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        header64.e_machine=cpu;
108785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
108885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* 16-align .rodata in the .o file, just in case */
108985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        paddingSize=sectionHeaders64[4].sh_offset & 0xf;
109085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(paddingSize!=0) {
109185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                paddingSize=0x10-paddingSize;
109285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                sectionHeaders64[4].sh_offset+=paddingSize;
109385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
109485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
109585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        sectionHeaders64[4].sh_size=(Elf64_Xword)size;
109685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
109785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        symbols64[1].st_size=(Elf64_Xword)size;
109885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
109985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* write .o headers */
110085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        T_FileStream_write(out, &header64, (int32_t)sizeof(header64));
110185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        T_FileStream_write(out, sectionHeaders64, (int32_t)sizeof(sectionHeaders64));
110285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        T_FileStream_write(out, symbols64, (int32_t)sizeof(symbols64));
110385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
110485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
110585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
110685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_write(out, sectionStrings, (int32_t)sizeof(sectionStrings));
110785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_write(out, entry, (int32_t)sizeof(entry));
110885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(paddingSize!=0) {
110985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        T_FileStream_write(out, padding, paddingSize);
111085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
1111103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM_HAS_WIN32_API
111285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* populate the .obj headers */
111385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_memset(&objHeader, 0, sizeof(objHeader));
111485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_memset(&symbols, 0, sizeof(symbols));
111585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_memset(&symbolNames, 0, sizeof(symbolNames));
111685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
111785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* write the linker export directive */
111885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strcpy(objHeader.linkerOptions, "-export:");
111985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    length=8;
112085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strcpy(objHeader.linkerOptions+length, entry);
112185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    length+=entryLength;
112285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strcpy(objHeader.linkerOptions+length, ",data ");
112385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    length+=6;
112485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
112585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* set the file header */
112685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    objHeader.fileHeader.Machine=cpu;
112785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    objHeader.fileHeader.NumberOfSections=2;
112885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    objHeader.fileHeader.TimeDateStamp=(DWORD)time(NULL);
112985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    objHeader.fileHeader.PointerToSymbolTable=IMAGE_SIZEOF_FILE_HEADER+2*IMAGE_SIZEOF_SECTION_HEADER+length+size; /* start of symbol table */
113085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    objHeader.fileHeader.NumberOfSymbols=1;
113185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
113285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* set the section for the linker options */
113385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strncpy((char *)objHeader.sections[0].Name, ".drectve", 8);
113485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    objHeader.sections[0].SizeOfRawData=length;
113585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    objHeader.sections[0].PointerToRawData=IMAGE_SIZEOF_FILE_HEADER+2*IMAGE_SIZEOF_SECTION_HEADER;
113685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    objHeader.sections[0].Characteristics=IMAGE_SCN_LNK_INFO|IMAGE_SCN_LNK_REMOVE|IMAGE_SCN_ALIGN_1BYTES;
113785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
113885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* set the data section */
113985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    uprv_strncpy((char *)objHeader.sections[1].Name, ".rdata", 6);
114085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    objHeader.sections[1].SizeOfRawData=size;
114185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    objHeader.sections[1].PointerToRawData=IMAGE_SIZEOF_FILE_HEADER+2*IMAGE_SIZEOF_SECTION_HEADER+length;
114285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    objHeader.sections[1].Characteristics=IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_ALIGN_16BYTES|IMAGE_SCN_MEM_READ;
114385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
114485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* set the symbol table */
114585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(entryLength<=8) {
114685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_strncpy((char *)symbols[0].N.ShortName, entry, entryLength);
114785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        symbolNames.sizeofLongNames=4;
114885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
114985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        symbols[0].N.Name.Short=0;
115085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        symbols[0].N.Name.Long=4;
115185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        symbolNames.sizeofLongNames=4+entryLength+1;
115285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_strcpy(symbolNames.longNames, entry);
115385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
115485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    symbols[0].SectionNumber=2;
115585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    symbols[0].StorageClass=IMAGE_SYM_CLASS_EXTERNAL;
115685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
115785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* write the file header and the linker options section */
115885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_write(out, &objHeader, objHeader.sections[1].PointerToRawData);
115985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else
116085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#   error "Unknown platform for CAN_GENERATE_OBJECTS."
116185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
116285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
116385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* copy the data file into section 2 */
116485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for(;;) {
116585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        length=T_FileStream_read(in, buffer, sizeof(buffer));
116685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(length==0) {
116785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
116885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
116985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        T_FileStream_write(out, buffer, (int32_t)length);
117085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
117185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1172103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_HAS_WIN32_API
117385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /* write the symbol table */
117485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_write(out, symbols, IMAGE_SIZEOF_SYMBOL);
117585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_write(out, &symbolNames, symbolNames.sizeofLongNames);
117685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
117785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
117885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(T_FileStream_error(in)) {
117985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: file read error while generating from file %s\n", filename);
118085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
118185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
118285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
118385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(T_FileStream_error(out)) {
118485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fprintf(stderr, "genccode: file write error while generating from file %s\n", filename);
118585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        exit(U_FILE_ACCESS_ERROR);
118685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
118785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
118885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_close(out);
118985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    T_FileStream_close(in);
119085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
119185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
1192