Ignore:
Timestamp:
Jan 21, 2018, 12:10:09 AM (6 years ago)
Author:
coas-nagasima
Message:

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

Location:
EcnlProtoTool/trunk/tcc-0.9.27
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/tcc-0.9.27/tccpe.c

    r321 r331  
    2121#include "tcc.h"
    2222
     23#define PE_MERGE_DATA
     24/* #define PE_PRINT_SECTIONS */
     25
    2326#ifndef _WIN32
    2427#define stricmp strcasecmp
    2528#define strnicmp strncasecmp
    26 #endif
    27 
    28 #ifndef MAX_PATH
    29 #define MAX_PATH 260
    30 #endif
    31 
    32 #define PE_MERGE_DATA
    33 // #define PE_PRINT_SECTIONS
     29#include <sys/stat.h> /* chmod() */
     30#endif
    3431
    3532#ifdef TCC_TARGET_X86_64
    3633# define ADDR3264 ULONGLONG
    37 #else
     34# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
     35# define REL_TYPE_DIRECT R_X86_64_64
     36# define R_XXX_THUNKFIX R_X86_64_PC32
     37# define R_XXX_RELATIVE R_X86_64_RELATIVE
     38# define IMAGE_FILE_MACHINE 0x8664
     39# define RSRC_RELTYPE 3
     40
     41#elif defined TCC_TARGET_ARM
    3842# define ADDR3264 DWORD
    39 #endif
    40 
    41 #ifdef _WIN32
    42 void dbg_printf (const char *fmt, ...)
    43 {
    44     char buffer[4000];
    45     va_list arg;
    46     int x;
    47     va_start(arg, fmt);
    48     x = vsprintf (buffer, fmt, arg);
    49     strcpy(buffer+x, "\n");
    50     OutputDebugString(buffer);
    51 }
    52 #endif
    53 
    54 /* ----------------------------------------------------------- */
     43# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
     44# define REL_TYPE_DIRECT R_ARM_ABS32
     45# define R_XXX_THUNKFIX R_ARM_ABS32
     46# define R_XXX_RELATIVE R_ARM_RELATIVE
     47# define IMAGE_FILE_MACHINE 0x01C0
     48# define RSRC_RELTYPE 7 /* ??? (not tested) */
     49
     50#elif defined TCC_TARGET_I386
     51# define ADDR3264 DWORD
     52# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
     53# define REL_TYPE_DIRECT R_386_32
     54# define R_XXX_THUNKFIX R_386_32
     55# define R_XXX_RELATIVE R_386_RELATIVE
     56# define IMAGE_FILE_MACHINE 0x014C
     57# define RSRC_RELTYPE 7 /* DIR32NB */
     58
     59#endif
     60
    5561#ifndef IMAGE_NT_SIGNATURE
    5662/* ----------------------------------------------------------- */
     
    224230#define IMAGE_REL_BASED_SECTION          6
    225231#define IMAGE_REL_BASED_REL32            7
     232#define IMAGE_REL_BASED_DIR64           10
    226233
    227234#pragma pack(pop)
     
    230237#endif /* ndef IMAGE_NT_SIGNATURE */
    231238/* ----------------------------------------------------------- */
     239
     240#ifndef IMAGE_REL_BASED_DIR64
     241# define IMAGE_REL_BASED_DIR64 10
     242#endif
     243
    232244#pragma pack(push, 1)
    233 
    234245struct pe_header
    235246{
     
    264275    WORD type;
    265276};
    266 
    267277#pragma pack(pop)
    268278
     
    337347    DWORD sizeofheaders;
    338348    ADDR3264 imagebase;
     349    const char *start_symbol;
    339350    DWORD start_addr;
    340351    DWORD imp_offs;
     
    363374static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym)
    364375{
    365     const char *name = symtab_section->link->data + sym->st_name;
    366     if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & 2))
     376    const char *name = (char*)symtab_section->link->data + sym->st_name;
     377    if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & ST_PE_STDCALL))
    367378        return name + 1;
    368379    return name;
     
    374385    const char *s, *p;
    375386    int sym_index = 0, n = 0;
     387    int a, err = 0;
    376388
    377389    do {
    378390        s = pe_export_name(s1, sym);
     391        a = 0;
    379392        if (n) {
    380393            /* second try: */
    381             if (sym->st_other & 2) {
     394            if (sym->st_other & ST_PE_STDCALL) {
    382395                /* try w/0 stdcall deco (windows API convention) */
    383396                p = strrchr(s, '@');
     
    387400            } else if (s[0] != '_') { /* try non-ansi function */
    388401                buffer[0] = '_', strcpy(buffer + 1, s);
    389             } else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */
    390                 strcpy(buffer, s + 6);
    391             } else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */
    392                 strcpy(buffer, s + 6);
     402            } else if (0 == memcmp(s, "__imp_", 6)) { /* mingw 2.0 */
     403                strcpy(buffer, s + 6), a = 1;
     404            } else if (0 == memcmp(s, "_imp__", 6)) { /* mingw 3.7 */
     405                strcpy(buffer, s + 6), a = 1;
    393406            } else {
    394                 break;
     407                continue;
    395408            }
    396409            s = buffer;
     
    398411        sym_index = find_elf_sym(s1->dynsymtab_section, s);
    399412        // printf("find (%d) %d %s\n", n, sym_index, s);
     413        if (sym_index
     414            && ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT
     415            && 0 == (sym->st_other & ST_PE_IMPORT)
     416            && 0 == a
     417            ) err = -1, sym_index = 0;
    400418    } while (0 == sym_index && ++n < 2);
    401     return sym_index;
     419    return n == 2 ? err : sym_index;
    402420}
    403421
     
    508526    {
    509527    /* IMAGE_FILE_HEADER filehdr */
    510 #if defined(TCC_TARGET_I386)
    511     0x014C,   /*WORD    Machine; */
    512 #elif defined(TCC_TARGET_X86_64)
    513     0x8664,   /*WORD    Machine; */
    514 #elif defined(TCC_TARGET_ARM)
    515     0x01C0,   /*WORD    Machine; */
    516 #endif
     528    IMAGE_FILE_MACHINE, /*WORD    Machine; */
    517529    0x0003, /*WORD    NumberOfSections; */
    518530    0x00000000, /*DWORD   TimeDateStamp; */
     
    623635            case sec_text:
    624636                pe_header.opthdr.BaseOfCode = addr;
    625                 pe_header.opthdr.AddressOfEntryPoint = addr + pe->start_addr;
    626637                break;
    627638
     
    664675        }
    665676
    666         pstrcpy((char*)psh->Name, sizeof psh->Name, sh_name);
     677        strncpy((char*)psh->Name, sh_name, sizeof psh->Name);
    667678
    668679        psh->Characteristics = pe_sec_flags[si->cls];
     
    676687            file_offset = pe_file_align(pe, file_offset + si->data_size);
    677688            psh->SizeOfRawData = file_offset - psh->PointerToRawData;
     689            if (si->cls == sec_text)
     690                pe_header.opthdr.SizeOfCode += psh->SizeOfRawData;
     691            else
     692                pe_header.opthdr.SizeOfInitializedData += psh->SizeOfRawData;
    678693        }
    679694    }
     
    681696    //pe_header.filehdr.TimeDateStamp = time(NULL);
    682697    pe_header.filehdr.NumberOfSections = pe->sec_count;
     698    pe_header.opthdr.AddressOfEntryPoint = pe->start_addr;
    683699    pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
    684700    pe_header.opthdr.ImageBase = pe->imagebase;
     
    688704    if (PE_DLL == pe->type)
    689705        pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL;
     706    pe_header.filehdr.Characteristics |= pe->s1->pe_characteristics;
    690707
    691708    sum = 0;
     
    708725    pe_fwrite(&pe_header.opthdr.CheckSum, sizeof pe_header.opthdr.CheckSum, op, NULL);
    709726    fclose (op);
     727#ifndef _WIN32
     728    chmod(pe->filename, 0777);
     729#endif
    710730
    711731    if (2 == pe->s1->verbose)
     
    717737}
    718738
    719 /*----------------------------------------------------------------------------*/
    720 
    721 #if defined(TCC_TARGET_X86_64)
    722 #define REL_TYPE_DIRECT R_X86_64_64
    723 #define R_XXX_THUNKFIX R_X86_64_PC32
    724 #define R_XXX_RELATIVE R_X86_64_RELATIVE
    725 
    726 #elif defined(TCC_TARGET_I386)
    727 #define REL_TYPE_DIRECT R_386_32
    728 #define R_XXX_THUNKFIX R_386_32
    729 #define R_XXX_RELATIVE R_386_RELATIVE
    730 
    731 #elif defined(TCC_TARGET_ARM)
    732 #define REL_TYPE_DIRECT R_ARM_ABS32
    733 #define R_XXX_THUNKFIX R_ARM_ABS32
    734 #define R_XXX_RELATIVE R_ARM_RELATIVE
    735 
    736 #endif
    737739/*----------------------------------------------------------------------------*/
    738740
     
    755757    p = tcc_mallocz(sizeof *p);
    756758    p->dll_index = dll_index;
    757     dynarray_add((void***)&pe->imp_info, &pe->imp_count, p);
     759    dynarray_add(&pe->imp_info, &pe->imp_count, p);
    758760
    759761found_dll:
     
    763765
    764766    s = tcc_mallocz(sizeof *s);
    765     dynarray_add((void***)&p->symbols, &p->sym_count, s);
     767    dynarray_add(&p->symbols, &p->sym_count, s);
    766768    s->sym_index = sym_index;
    767769    return s;
     770}
     771
     772void pe_free_imports(struct pe_info *pe)
     773{
     774    int i;
     775    for (i = 0; i < pe->imp_count; ++i) {
     776        struct pe_import_info *p = pe->imp_info[i];
     777        dynarray_reset(&p->symbols, &p->sym_count);
     778    }
     779    dynarray_reset(&pe->imp_info, &pe->imp_count);
    768780}
    769781
     
    819831                ElfW(Sym) *imp_sym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index;
    820832                ElfW(Sym) *org_sym = (ElfW(Sym) *)symtab_section->data + iat_index;
    821                 const char *name = pe->s1->dynsymtab_section->link->data + imp_sym->st_name;
     833                const char *name = (char*)pe->s1->dynsymtab_section->link->data + imp_sym->st_name;
     834                int ordinal;
    822835
    823836                org_sym->st_value = thk_ptr;
    824837                org_sym->st_shndx = pe->thunk->sh_num;
    825                 v = pe->thunk->data_offset + rva_base;
    826                 section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */
    827                 put_elf_str(pe->thunk, name);
     838
     839                if (dllref)
     840                    v = 0, ordinal = imp_sym->st_value; /* ordinal from pe_load_def */
     841                else
     842                    ordinal = 0, v = imp_sym->st_value; /* address from tcc_add_symbol() */
     843
    828844#ifdef TCC_IS_NATIVE
    829845                if (pe->type == PE_RUN) {
    830                     v = imp_sym->st_value;
    831846                    if (dllref) {
    832847                        if ( !dllref->handle )
    833848                            dllref->handle = LoadLibrary(dllref->name);
    834                         v = (ADDR3264)GetProcAddress(dllref->handle, name);
     849                        v = (ADDR3264)GetProcAddress(dllref->handle, ordinal?(char*)0+ordinal:name);
    835850                    }
    836851                    if (!v)
    837                         tcc_error_noabort("undefined symbol '%s'", name);
     852                        tcc_error_noabort("can't build symbol '%s'", name);
     853                } else
     854#endif
     855                if (ordinal) {
     856                    v = ordinal | (ADDR3264)1 << (sizeof(ADDR3264)*8 - 1);
     857                } else {
     858                    v = pe->thunk->data_offset + rva_base;
     859                    section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */
     860                    put_elf_str(pe->thunk, name);
    838861                }
    839 #endif
     862
    840863            } else {
    841864                v = 0; /* last entry is zero */
    842865            }
     866
    843867            *(ADDR3264*)(pe->thunk->data+thk_ptr) =
    844868            *(ADDR3264*)(pe->thunk->data+ent_ptr) = v;
     
    847871        }
    848872        dll_ptr += sizeof(IMAGE_IMPORT_DESCRIPTOR);
    849         dynarray_reset(&p->symbols, &p->sym_count);
    850     }
    851     dynarray_reset(&pe->imp_info, &pe->imp_count);
     873    }
    852874}
    853875
     
    877899
    878900    FILE *op;
    879     char buf[MAX_PATH];
     901    char buf[260];
    880902    const char *dllname;
    881903    const char *name;
     
    888910        sym = (ElfW(Sym)*)symtab_section->data + sym_index;
    889911        name = pe_export_name(pe->s1, sym);
    890         if ((sym->st_other & 1)
     912        if ((sym->st_other & ST_PE_EXPORT)
    891913            /* export only symbols from actually written sections */
    892914            && pe->s1->sections[sym->st_shndx]->sh_addr) {
     
    894916            p->index = sym_index;
    895917            p->name = name;
    896             dynarray_add((void***)&sorted, &sym_count, p);
     918            dynarray_add(&sorted, &sym_count, p);
    897919        }
    898920#if 0
    899         if (sym->st_other & 1)
     921        if (sym->st_other & ST_PE_EXPORT)
    900922            printf("export: %s\n", name);
    901         if (sym->st_other & 2)
     923        if (sym->st_other & ST_PE_STDCALL)
    902924            printf("stdcall: %s\n", name);
    903925#endif
     
    933955    pstrcpy(buf, sizeof buf, pe->filename);
    934956    strcpy(tcc_fileextension(buf), ".def");
    935     op = fopen(buf, "w");
     957    op = fopen(buf, "wb");
    936958    if (NULL == op) {
    937959        tcc_error_noabort("could not create '%s': %s", buf, strerror(errno));
     
    939961        fprintf(op, "LIBRARY %s\n\nEXPORTS\n", dllname);
    940962        if (pe->s1->verbose)
    941             printf("<- %s (%d symbols)\n", buf, sym_count);
     963            printf("<- %s (%d symbol%s)\n", buf, sym_count, &"s"[sym_count < 2]);
    942964    }
    943965#endif
     
    946968    {
    947969        p = sorted[ord], sym_index = p->index, name = p->name;
    948         /* insert actual address later in pe_relocate_rva */
     970        /* insert actual address later in relocate_section() */
    949971        put_elf_reloc(symtab_section, pe->thunk,
    950972            func_o, R_XXX_RELATIVE, sym_index);
     
    9911013            if ((addr -= offset)  < (1<<12)) { /* one block spans 4k addresses */
    9921014                WORD *wp = section_ptr_add(pe->reloc, sizeof (WORD));
    993                 *wp = addr | IMAGE_REL_BASED_HIGHLOW<<12;
     1015                *wp = addr | PE_IMAGE_REL<<12;
    9941016                ++count;
    9951017                continue;
     
    10651087    Section *s;
    10661088
     1089    if (PE_DLL == pe->type)
     1090        pe->reloc = new_section(pe->s1, ".reloc", SHT_PROGBITS, 0);
     1091
    10671092    // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
    10681093
     
    11571182}
    11581183
    1159 /* ------------------------------------------------------------- */
    1160 static void pe_relocate_rva (struct pe_info *pe, Section *s)
    1161 {
    1162     Section *sr = s->reloc;
    1163     ElfW_Rel *rel, *rel_end;
    1164     rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
    1165     for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
    1166         if (ELFW(R_TYPE)(rel->r_info) == R_XXX_RELATIVE) {
    1167             int sym_index = ELFW(R_SYM)(rel->r_info);
    1168             DWORD addr = s->sh_addr;
    1169             if (sym_index) {
    1170                 ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;
    1171                 addr = sym->st_value;
    1172             }
    1173             // printf("reloc rva %08x %08x %s\n", (DWORD)rel->r_offset, addr, s->name);
    1174             *(DWORD*)(s->data + rel->r_offset) += addr - pe->imagebase;
    1175         }
    1176     }
    1177 }
    1178 
    11791184/*----------------------------------------------------------------------------*/
    11801185
     
    12081213        if (sym->st_shndx == SHN_UNDEF) {
    12091214
    1210             const char *name = symtab_section->link->data + sym->st_name;
     1215            const char *name = (char*)symtab_section->link->data + sym->st_name;
    12111216            unsigned type = ELFW(ST_TYPE)(sym->st_info);
    12121217            int imp_sym = pe_find_import(pe->s1, sym);
    12131218            struct import_symbol *is;
    12141219
    1215             if (0 == imp_sym)
     1220            if (imp_sym <= 0)
    12161221                goto not_found;
    12171222
     
    12711276                sym->st_value = offset;
    12721277                sym->st_shndx = text_section->sh_num;
    1273                 sym->st_other &= ~1; /* do not export */
     1278                sym->st_other &= ~ST_PE_EXPORT; /* do not export */
    12741279                continue;
    12751280            }
     
    12841289
    12851290        not_found:
    1286             tcc_error_noabort("undefined symbol '%s'", name);
     1291            if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
     1292                /* STB_WEAK undefined symbols are accepted */
     1293                continue;
     1294            tcc_error_noabort("undefined symbol '%s'%s", name,
     1295                imp_sym < 0 ? ", missing __declspec(dllimport)?":"");
    12871296            ret = -1;
    12881297
     
    12901299                   && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
    12911300            /* if -rdynamic option, then export all non local symbols */
    1292             sym->st_other |= 1;
     1301            sym->st_other |= ST_PE_EXPORT;
    12931302        }
    12941303    }
     
    13001309static void pe_print_section(FILE * f, Section * s)
    13011310{
    1302     /* just if you'r curious */
     1311    /* just if you're curious */
    13031312    BYTE *p, *e, b;
    13041313    int i, n, l, m;
     
    14381447/* helper function for load/store to insert one more indirection */
    14391448
     1449#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
    14401450ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2)
    14411451{
    1442     Sym *sym;
    1443     ElfW(Sym) *esym;
    14441452    int r2;
    1445 
    14461453    if ((sv->r & (VT_VALMASK|VT_SYM)) != (VT_CONST|VT_SYM) || (sv->r2 != VT_CONST))
    14471454        return sv;
    1448     sym = sv->sym;
    1449     if ((sym->type.t & (VT_EXTERN|VT_STATIC)) != VT_EXTERN)
     1455    if (!sv->sym->a.dllimport)
    14501456        return sv;
    1451     if (!sym->c)
    1452         put_extern_sym(sym, NULL, 0, 0);
    1453     esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
    1454     if (!(esym->st_other & 4))
    1455         return sv;
    1456 
    1457     // printf("import %04x %04x %04x %s\n", sv->type.t, sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL));
    1458 
     1457    // printf("import %04x %04x %04x %s\n", sv->type.t, sv->sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL));
    14591458    memset(v2, 0, sizeof *v2);
    14601459    v2->type.t = VT_PTR;
     
    14651464    load(r2, v2);
    14661465    v2->r = r2;
    1467 
    1468     if (sv->c.ui) {
     1466    if ((uint32_t)sv->c.i) {
    14691467        vpushv(v2);
    1470         vpushi(sv->c.ui);
     1468        vpushi(sv->c.i);
    14711469        gen_opi('+');
    14721470        *v2 = *vtop--;
    14731471    }
    1474 
    14751472    v2->type.t = sv->type.t;
    14761473    v2->r |= sv->r & VT_LVAL;
    14771474    return v2;
    14781475}
     1476#endif
    14791477
    14801478ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value)
    14811479{
    1482     return add_elf_sym(
     1480    return set_elf_sym(
    14831481        s1->dynsymtab_section,
    14841482        value,
     
    15001498    dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
    15011499    strcpy(dllref->name, dllname);
    1502     dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
     1500    dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
    15031501    return s1->nb_loaded_dlls;
    15041502}
     
    15101508    lseek(fd, offset, SEEK_SET);
    15111509    return len == read(fd, buffer, len);
     1510}
     1511
     1512/* ------------------------------------------------------------- */
     1513
     1514PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
     1515{
     1516    int l, i, n, n0, ret;
     1517    char *p;
     1518    int fd;
     1519
     1520    IMAGE_SECTION_HEADER ish;
     1521    IMAGE_EXPORT_DIRECTORY ied;
     1522    IMAGE_DOS_HEADER dh;
     1523    IMAGE_FILE_HEADER ih;
     1524    DWORD sig, ref, addr, ptr, namep;
     1525
     1526    int pef_hdroffset, opt_hdroffset, sec_hdroffset;
     1527
     1528    n = n0 = 0;
     1529    p = NULL;
     1530    ret = -1;
     1531
     1532    fd = open(filename, O_RDONLY | O_BINARY);
     1533    if (fd < 0)
     1534        goto the_end_1;
     1535    ret = 1;
     1536    if (!read_mem(fd, 0, &dh, sizeof dh))
     1537        goto the_end;
     1538    if (!read_mem(fd, dh.e_lfanew, &sig, sizeof sig))
     1539        goto the_end;
     1540    if (sig != 0x00004550)
     1541        goto the_end;
     1542    pef_hdroffset = dh.e_lfanew + sizeof sig;
     1543    if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
     1544        goto the_end;
     1545    opt_hdroffset = pef_hdroffset + sizeof ih;
     1546    if (ih.Machine == 0x014C) {
     1547        IMAGE_OPTIONAL_HEADER32 oh;
     1548        sec_hdroffset = opt_hdroffset + sizeof oh;
     1549        if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
     1550            goto the_end;
     1551        if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
     1552            goto the_end_0;
     1553        addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
     1554    } else if (ih.Machine == 0x8664) {
     1555        IMAGE_OPTIONAL_HEADER64 oh;
     1556        sec_hdroffset = opt_hdroffset + sizeof oh;
     1557        if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
     1558            goto the_end;
     1559        if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
     1560            goto the_end_0;
     1561        addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
     1562    } else
     1563        goto the_end;
     1564
     1565    //printf("addr: %08x\n", addr);
     1566    for (i = 0; i < ih.NumberOfSections; ++i) {
     1567        if (!read_mem(fd, sec_hdroffset + i * sizeof ish, &ish, sizeof ish))
     1568            goto the_end;
     1569        //printf("vaddr: %08x\n", ish.VirtualAddress);
     1570        if (addr >= ish.VirtualAddress && addr < ish.VirtualAddress + ish.SizeOfRawData)
     1571            goto found;
     1572    }
     1573    goto the_end_0;
     1574
     1575found:
     1576    ref = ish.VirtualAddress - ish.PointerToRawData;
     1577    if (!read_mem(fd, addr - ref, &ied, sizeof ied))
     1578        goto the_end;
     1579
     1580    namep = ied.AddressOfNames - ref;
     1581    for (i = 0; i < ied.NumberOfNames; ++i) {
     1582        if (!read_mem(fd, namep, &ptr, sizeof ptr))
     1583            goto the_end;
     1584        namep += sizeof ptr;
     1585        for (l = 0;;) {
     1586            if (n+1 >= n0)
     1587                p = tcc_realloc(p, n0 = n0 ? n0 * 2 : 256);
     1588            if (!read_mem(fd, ptr - ref + l++, p + n, 1)) {
     1589                tcc_free(p), p = NULL;
     1590                goto the_end;
     1591            }
     1592            if (p[n++] == 0)
     1593                break;
     1594        }
     1595    }
     1596    if (p)
     1597        p[n] = 0;
     1598the_end_0:
     1599    ret = 0;
     1600the_end:
     1601    close(fd);
     1602the_end_1:
     1603    *pp = p;
     1604    return ret;
    15121605}
    15131606
     
    15211614    struct pe_rsrc_header hdr;
    15221615    Section *rsrc_section;
    1523     int i, ret = -1;
     1616    int i, ret = -1, sym_index;
    15241617    BYTE *ptr;
    15251618    unsigned offs;
     
    15281621        goto quit;
    15291622
    1530     if (hdr.filehdr.Machine != 0x014C
     1623    if (hdr.filehdr.Machine != IMAGE_FILE_MACHINE
    15311624        || hdr.filehdr.NumberOfSections != 1
    1532         || strcmp(hdr.sectionhdr.Name, ".rsrc") != 0)
     1625        || strcmp((char*)hdr.sectionhdr.Name, ".rsrc") != 0)
    15331626        goto quit;
    15341627
     
    15391632        goto quit;
    15401633    offs = hdr.sectionhdr.PointerToRelocations;
    1541     for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i)
    1542     {
     1634    sym_index = put_elf_sym(symtab_section, 0, 0, 0, 0, rsrc_section->sh_num, ".rsrc");
     1635    for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i) {
    15431636        struct pe_rsrc_reloc rel;
    15441637        if (!read_mem(fd, offs, &rel, sizeof rel))
    15451638            goto quit;
    15461639        // printf("rsrc_reloc: %x %x %x\n", rel.offset, rel.size, rel.type);
    1547         if (rel.type != 7) /* DIR32NB */
     1640        if (rel.type != RSRC_RELTYPE)
    15481641            goto quit;
    15491642        put_elf_reloc(symtab_section, rsrc_section,
    1550             rel.offset, R_XXX_RELATIVE, 0);
     1643            rel.offset, R_XXX_RELATIVE, sym_index);
    15511644        offs += sizeof rel;
    15521645    }
     
    15571650
    15581651/* ------------------------------------------------------------- */
     1652
    15591653static char *trimfront(char *p)
    15601654{
    15611655    while (*p && (unsigned char)*p <= ' ')
    1562         ++p;
     1656        ++p;
    15631657    return p;
    15641658}
     
    15671661{
    15681662    while (e > a && (unsigned char)e[-1] <= ' ')
    1569         --e;
     1663        --e;
    15701664    *e = 0;;
    15711665    return a;
    15721666}
    15731667
    1574 static char *get_line(char *line, int size, int fd)
    1575 {
    1576     int n;
    1577     for (n = 0; n < size - 1; )
    1578         if (read(fd, line + n, 1) < 1 || line[n++] == '\n')
    1579             break;
    1580     if (0 == n)
    1581         return NULL;
    1582     trimback(line, line + n);
    1583     return trimfront(line);
    1584 }
    1585 
    15861668/* ------------------------------------------------------------- */
    15871669static int pe_load_def(TCCState *s1, int fd)
    15881670{
    1589     int state = 0, ret = -1, dllindex = 0;
    1590     char line[400], dllname[80], *p;
    1591 
    1592     for (;;) {
    1593         p = get_line(line, sizeof line, fd);
    1594         if (NULL == p)
    1595             break;
     1671    int state = 0, ret = -1, dllindex = 0, ord;
     1672    char line[400], dllname[80], *p, *x;
     1673    FILE *fp;
     1674
     1675    fp = fdopen(dup(fd), "rb");
     1676    while (fgets(line, sizeof line, fp))
     1677    {
     1678        p = trimfront(trimback(line, strchr(line, 0)));
    15961679        if (0 == *p || ';' == *p)
    15971680            continue;
     1681
    15981682        switch (state) {
    15991683        case 0:
     
    16131697            dllindex = add_dllref(s1, dllname);
    16141698            ++state;
    1615 
     1699            /* fall through */
    16161700        default:
    1617             pe_putimport(s1, dllindex, p, 0);
     1701            /* get ordinal and will store in sym->st_value */
     1702            ord = 0;
     1703            x = strchr(p, ' ');
     1704            if (x) {
     1705                *x = 0, x = strrchr(x + 1, '@');
     1706                if (x) {
     1707                    char *d;
     1708                    ord = (int)strtol(x + 1, &d, 10);
     1709                    if (*d)
     1710                        ord = 0;
     1711                }
     1712            }
     1713            pe_putimport(s1, dllindex, p, ord);
    16181714            continue;
    16191715        }
     
    16211717    ret = 0;
    16221718quit:
     1719    fclose(fp);
    16231720    return ret;
    16241721}
    16251722
    16261723/* ------------------------------------------------------------- */
    1627 #define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
    1628 #include "win32/tools/tiny_impdef.c"
    1629 
    1630 static int pe_load_dll(TCCState *s1, const char *dllname, int fd)
     1724static int pe_load_dll(TCCState *s1, const char *filename)
    16311725{
    16321726    char *p, *q;
    1633     int index;
    1634     p = get_export_names(fd);
    1635     if (!p)
     1727    int index, ret;
     1728
     1729    ret = tcc_get_dllexports(filename, &p);
     1730    if (ret) {
    16361731        return -1;
    1637     index = add_dllref(s1, dllname);
    1638     for (q = p; *q; q += 1 + strlen(q))
    1639         pe_putimport(s1, index, q, 0);
    1640     tcc_free(p);
     1732    } else if (p) {
     1733        index = add_dllref(s1, tcc_basename(filename));
     1734        for (q = p; *q; q += 1 + strlen(q))
     1735            pe_putimport(s1, index, q, 0);
     1736        tcc_free(p);
     1737    }
    16411738    return 0;
    16421739}
     
    16511748    else if (pe_load_res(s1, fd) == 0)
    16521749        ret = 0;
    1653     else if (read_mem(fd, 0, buf, sizeof buf) && 0 == strncmp(buf, "MZ", 2))
    1654         ret = pe_load_dll(s1, tcc_basename(filename), fd);
     1750    else if (read_mem(fd, 0, buf, 4) && 0 == memcmp(buf, "MZ\220", 4))
     1751        ret = pe_load_dll(s1, filename);
    16551752    return ret;
    16561753}
     
    16631760        s1->uw_pdata = find_section(tcc_state, ".pdata");
    16641761        s1->uw_pdata->sh_addralign = 4;
    1665         s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, NULL);
    1666     }
    1667 
     1762    }
     1763    if (0 == s1->uw_sym)
     1764        s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, ".uw_base");
    16681765    if (0 == s1->uw_offs) {
    16691766        /* As our functions all have the same stackframe, we use one entry for all */
     
    17141811    /* put relocations on it */
    17151812    for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress)
    1716         put_elf_reloc(symtab_section, pd, o,  R_X86_64_RELATIVE, s1->uw_sym);
     1813        put_elf_reloc(symtab_section, pd, o, R_XXX_RELATIVE, s1->uw_sym);
    17171814}
    17181815#endif
     
    17271824{
    17281825    const char *start_symbol;
    1729     ADDR3264 addr = 0;
    17301826    int pe_type = 0;
     1827    int unicode_entry = 0;
    17311828
    17321829    if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16")))
    17331830        pe_type = PE_GUI;
     1831    else
     1832    if (find_elf_sym(symtab_section, PE_STDSYM("wWinMain","@16"))) {
     1833        pe_type = PE_GUI;
     1834        unicode_entry = PE_GUI;
     1835    }
    17341836    else
    17351837    if (TCC_OUTPUT_DLL == s1->output_type) {
     
    17381840        s1->output_type = TCC_OUTPUT_EXE;
    17391841    }
    1740     else
     1842    else {
    17411843        pe_type = PE_EXE;
     1844        if (find_elf_sym(symtab_section, "wmain"))
     1845            unicode_entry = PE_EXE;
     1846    }
    17421847
    17431848    start_symbol =
    17441849        TCC_OUTPUT_MEMORY == s1->output_type
    1745         ? PE_GUI == pe_type ? "__runwinmain" : "_main"
     1850        ? PE_GUI == pe_type ? (unicode_entry ? "__runwwinmain" : "__runwinmain")
     1851            : (unicode_entry ? "__runwmain" : "__runmain")
    17461852        : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12")
    1747         : PE_GUI == pe_type ? "__winstart" : "__start"
     1853            : PE_GUI == pe_type ? (unicode_entry ? "__wwinstart": "__winstart")
     1854                : (unicode_entry ? "__wstart" : "__start")
    17481855        ;
    17491856
    1750     if (!s1->leading_underscore || strchr(start_symbol, '@')) {
     1857    if (!s1->leading_underscore || strchr(start_symbol, '@'))
    17511858        ++start_symbol;
    1752         if (start_symbol[0] != '_')
    1753             start_symbol = NULL;
    1754     }
    17551859
    17561860    /* grab the startup code from libtcc1 */
    1757     if (start_symbol)
    1758         add_elf_sym(symtab_section,
    1759             0, 0,
    1760             ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    1761             SHN_UNDEF, start_symbol);
     1861#ifdef TCC_IS_NATIVE
     1862    if (TCC_OUTPUT_MEMORY != s1->output_type || s1->runtime_main)
     1863#endif
     1864    set_elf_sym(symtab_section,
     1865        0, 0,
     1866        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
     1867        SHN_UNDEF, start_symbol);
     1868
     1869    tcc_add_pragma_libs(s1);
    17621870
    17631871    if (0 == s1->nostdlib) {
    17641872        static const char *libs[] = {
    1765             "libtcc1.a", "msvcrt", "kernel32", "", "user32", "gdi32", NULL
     1873            TCC_LIBTCC1, "msvcrt", "kernel32", "", "user32", "gdi32", NULL
    17661874        };
    17671875        const char **pp, *p;
     
    17701878                if (PE_DLL != pe_type && PE_GUI != pe_type)
    17711879                    break;
    1772             } else if (pp == libs ? tcc_add_dll(s1, p, 0) : tcc_add_library(s1, p)) {
    1773                 tcc_error_noabort("cannot find library: %s", p);
    1774                 break;
     1880            } else if (pp == libs && tcc_add_dll(s1, p, 0) >= 0) {
     1881                continue;
     1882            } else {
     1883                tcc_add_library_err(s1, p);
    17751884            }
    17761885        }
     
    17791888    if (TCC_OUTPUT_MEMORY == s1->output_type)
    17801889        pe_type = PE_RUN;
    1781 
    1782     if (start_symbol) {
    1783         addr = get_elf_sym_addr(s1, start_symbol, 1);
    1784         if (PE_RUN == pe_type && addr)
    1785             /* for -run GUI's, put '_runwinmain' instead of 'main' */
    1786             add_elf_sym(symtab_section,
    1787                     addr, 0,
    1788                     ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    1789                     text_section->sh_num, "main");
    1790     }
    1791 
    17921890    pe->type = pe_type;
    1793     pe->start_addr = addr;
    1794 }
    1795 
    1796 ST_FUNC int pe_output_file(TCCState * s1, const char *filename)
     1891    pe->start_symbol = start_symbol;
     1892}
     1893
     1894static void pe_set_options(TCCState * s1, struct pe_info *pe)
     1895{
     1896    if (PE_DLL == pe->type) {
     1897        /* XXX: check if is correct for arm-pe target */
     1898        pe->imagebase = 0x10000000;
     1899    } else {
     1900#if defined(TCC_TARGET_ARM)
     1901        pe->imagebase = 0x00010000;
     1902#else
     1903        pe->imagebase = 0x00400000;
     1904#endif
     1905    }
     1906
     1907#if defined(TCC_TARGET_ARM)
     1908    /* we use "console" subsystem by default */
     1909    pe->subsystem = 9;
     1910#else
     1911    if (PE_DLL == pe->type || PE_GUI == pe->type)
     1912        pe->subsystem = 2;
     1913    else
     1914        pe->subsystem = 3;
     1915#endif
     1916    /* Allow override via -Wl,-subsystem=... option */
     1917    if (s1->pe_subsystem != 0)
     1918        pe->subsystem = s1->pe_subsystem;
     1919
     1920    /* set default file/section alignment */
     1921    if (pe->subsystem == 1) {
     1922        pe->section_align = 0x20;
     1923        pe->file_align = 0x20;
     1924    } else {
     1925        pe->section_align = 0x1000;
     1926        pe->file_align = 0x200;
     1927    }
     1928
     1929    if (s1->section_align != 0)
     1930        pe->section_align = s1->section_align;
     1931    if (s1->pe_file_align != 0)
     1932        pe->file_align = s1->pe_file_align;
     1933
     1934    if ((pe->subsystem >= 10) && (pe->subsystem <= 12))
     1935        pe->imagebase = 0;
     1936
     1937    if (s1->has_text_addr)
     1938        pe->imagebase = s1->text_addr;
     1939}
     1940
     1941ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
    17971942{
    17981943    int ret;
     
    18061951    tcc_add_bcheck(s1);
    18071952    pe_add_runtime(s1, &pe);
    1808     relocate_common_syms(); /* assign bss adresses */
    1809     tcc_add_linker_symbols(s1);
     1953    resolve_common_syms(s1);
     1954    pe_set_options(s1, &pe);
    18101955
    18111956    ret = pe_check_symbols(&pe);
     
    18131958        ;
    18141959    else if (filename) {
    1815         if (PE_DLL == pe.type) {
    1816             pe.reloc = new_section(pe.s1, ".reloc", SHT_PROGBITS, 0);
    1817             /* XXX: check if is correct for arm-pe target */
    1818             pe.imagebase = 0x10000000;
    1819         } else {
    1820 #if defined(TCC_TARGET_ARM)
    1821             pe.imagebase = 0x00010000;
    1822 #else
    1823             pe.imagebase = 0x00400000;
    1824 #endif
    1825         }
    1826 
    1827 #if defined(TCC_TARGET_ARM)
    1828         /* we use "console" subsystem by default */
    1829         pe.subsystem = 9;
    1830 #else
    1831         if (PE_DLL == pe.type || PE_GUI == pe.type)
    1832             pe.subsystem = 2;
    1833         else
    1834             pe.subsystem = 3;
    1835 #endif
    1836         /* Allow override via -Wl,-subsystem=... option */
    1837         if (s1->pe_subsystem != 0)
    1838             pe.subsystem = s1->pe_subsystem;
    1839 
    1840         /* set default file/section alignment */
    1841         if (pe.subsystem == 1) {
    1842             pe.section_align = 0x20;
    1843             pe.file_align = 0x20;
    1844         } else {
    1845             pe.section_align = 0x1000;
    1846             pe.file_align = 0x200;
    1847         }
    1848 
    1849         if (s1->section_align != 0)
    1850             pe.section_align = s1->section_align;
    1851         if (s1->pe_file_align != 0)
    1852             pe.file_align = s1->pe_file_align;
    1853 
    1854         if ((pe.subsystem >= 10) && (pe.subsystem <= 12))
    1855             pe.imagebase = 0;
    1856 
    1857         if (s1->has_text_addr)
    1858             pe.imagebase = s1->text_addr;
    1859 
    18601960        pe_assign_addresses(&pe);
    1861         relocate_syms(s1, 0);
     1961        relocate_syms(s1, s1->symtab, 0);
     1962        s1->pe_imagebase = pe.imagebase;
    18621963        for (i = 1; i < s1->nb_sections; ++i) {
    18631964            Section *s = s1->sections[i];
    18641965            if (s->reloc) {
    18651966                relocate_section(s1, s);
    1866                 pe_relocate_rva(&pe, s);
    18671967            }
    18681968        }
     1969        pe.start_addr = (DWORD)
     1970            ((uintptr_t)tcc_get_symbol_err(s1, pe.start_symbol)
     1971                - pe.imagebase);
    18691972        if (s1->nb_errors)
    18701973            ret = -1;
     
    18761979        pe.thunk = data_section;
    18771980        pe_build_imports(&pe);
    1878 #endif
    1879     }
     1981        s1->runtime_main = pe.start_symbol;
     1982#ifdef TCC_TARGET_X86_64
     1983        s1->uw_pdata = find_section(s1, ".pdata");
     1984#endif
     1985#endif
     1986    }
     1987
     1988    pe_free_imports(&pe);
    18801989
    18811990#ifdef PE_PRINT_SECTIONS
Note: See TracChangeset for help on using the changeset viewer.