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