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/tccelf.c

    r321 r331  
    11/*
    22 *  ELF file handling for TCC
    3  * 
     3 *
    44 *  Copyright (c) 2001-2004 Fabrice Bellard
    55 *
     
    2121#include "tcc.h"
    2222
     23/* Define this to get some debug output during relocation processing.  */
     24#undef DEBUG_RELOC
     25
     26/********************************************************/
     27/* global variables */
     28
     29ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
     30ST_DATA Section *common_section;
     31ST_DATA Section *cur_text_section; /* current section where function code is generated */
     32#ifdef CONFIG_TCC_ASM
     33ST_DATA Section *last_text_section; /* to handle .previous asm directive */
     34#endif
     35#ifdef CONFIG_TCC_BCHECK
     36/* bound check related sections */
     37ST_DATA Section *bounds_section; /* contains global data bound description */
     38ST_DATA Section *lbounds_section; /* contains local data bound description */
     39#endif
     40/* symbol sections */
     41ST_DATA Section *symtab_section;
     42/* debug sections */
     43ST_DATA Section *stab_section, *stabstr_section;
     44
     45/* XXX: avoid static variable */
    2346static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
     47
     48/* special flag to indicate that the section should not be linked to the other ones */
     49#define SHF_PRIVATE 0x80000000
     50/* section is dynsymtab_section */
     51#define SHF_DYNSYM 0x40000000
     52
     53/* ------------------------------------------------------------------------- */
     54
     55ST_FUNC void tccelf_new(TCCState *s)
     56{
     57    /* no section zero */
     58    dynarray_add(&s->sections, &s->nb_sections, NULL);
     59
     60    /* create standard sections */
     61    text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
     62    data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
     63    bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
     64    common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
     65    common_section->sh_num = SHN_COMMON;
     66
     67    /* symbols are always generated for linking stage */
     68    symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
     69                                ".strtab",
     70                                ".hashtab", SHF_PRIVATE);
     71    s->symtab = symtab_section;
     72
     73    /* private symbol table for dynamic symbols */
     74    s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
     75                                      ".dynstrtab",
     76                                      ".dynhashtab", SHF_PRIVATE);
     77    get_sym_attr(s, 0, 1);
     78}
     79
     80#ifdef CONFIG_TCC_BCHECK
     81ST_FUNC void tccelf_bounds_new(TCCState *s)
     82{
     83    /* create bounds sections */
     84    bounds_section = new_section(s, ".bounds",
     85                                 SHT_PROGBITS, SHF_ALLOC);
     86    lbounds_section = new_section(s, ".lbounds",
     87                                  SHT_PROGBITS, SHF_ALLOC);
     88}
     89#endif
     90
     91ST_FUNC void tccelf_stab_new(TCCState *s)
     92{
     93    stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
     94    stab_section->sh_entsize = sizeof(Stab_Sym);
     95    stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
     96    put_elf_str(stabstr_section, "");
     97    stab_section->link = stabstr_section;
     98    /* put first entry */
     99    put_stabs("", 0, 0, 0, 0);
     100}
     101
     102static void free_section(Section *s)
     103{
     104    tcc_free(s->data);
     105}
     106
     107ST_FUNC void tccelf_delete(TCCState *s1)
     108{
     109    int i;
     110
     111    /* free all sections */
     112    for(i = 1; i < s1->nb_sections; i++)
     113        free_section(s1->sections[i]);
     114    dynarray_reset(&s1->sections, &s1->nb_sections);
     115
     116    for(i = 0; i < s1->nb_priv_sections; i++)
     117        free_section(s1->priv_sections[i]);
     118    dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
     119
     120    /* free any loaded DLLs */
     121#ifdef TCC_IS_NATIVE
     122    for ( i = 0; i < s1->nb_loaded_dlls; i++) {
     123        DLLReference *ref = s1->loaded_dlls[i];
     124        if ( ref->handle )
     125# ifdef _WIN32
     126            FreeLibrary((HMODULE)ref->handle);
     127# else
     128            dlclose(ref->handle);
     129# endif
     130    }
     131#endif
     132    /* free loaded dlls array */
     133    dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
     134    tcc_free(s1->sym_attrs);
     135
     136    symtab_section = NULL; /* for tccrun.c:rt_printline() */
     137}
     138
     139/* save section data state */
     140ST_FUNC void tccelf_begin_file(TCCState *s1)
     141{
     142    Section *s; int i;
     143    for (i = 1; i < s1->nb_sections; i++) {
     144        s = s1->sections[i];
     145        s->sh_offset = s->data_offset;
     146    }
     147    /* disable symbol hashing during compilation */
     148    s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
     149#if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
     150    s1->uw_sym = 0;
     151#endif
     152}
     153
     154/* At the end of compilation, convert any UNDEF syms to global, and merge
     155   with previously existing symbols */
     156ST_FUNC void tccelf_end_file(TCCState *s1)
     157{
     158    Section *s = s1->symtab;
     159    int first_sym, nb_syms, *tr, i;
     160
     161    first_sym = s->sh_offset / sizeof (ElfSym);
     162    nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
     163    s->data_offset = s->sh_offset;
     164    s->link->data_offset = s->link->sh_offset;
     165    s->hash = s->reloc, s->reloc = NULL;
     166    tr = tcc_mallocz(nb_syms * sizeof *tr);
     167
     168    for (i = 0; i < nb_syms; ++i) {
     169        ElfSym *sym = (ElfSym*)s->data + first_sym + i;
     170        if (sym->st_shndx == SHN_UNDEF
     171            && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
     172            sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
     173        tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
     174            sym->st_other, sym->st_shndx, s->link->data + sym->st_name);
     175    }
     176    /* now update relocations */
     177    for (i = 1; i < s1->nb_sections; i++) {
     178        Section *sr = s1->sections[i];
     179        if (sr->sh_type == SHT_RELX && sr->link == s) {
     180            ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
     181            ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
     182            for (; rel < rel_end; ++rel) {
     183                int n = ELFW(R_SYM)(rel->r_info) - first_sym;
     184                //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
     185                rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
     186            }
     187        }
     188    }
     189    tcc_free(tr);
     190}
     191
     192ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
     193{
     194    Section *sec;
     195
     196    sec = tcc_mallocz(sizeof(Section) + strlen(name));
     197    strcpy(sec->name, name);
     198    sec->sh_type = sh_type;
     199    sec->sh_flags = sh_flags;
     200    switch(sh_type) {
     201    case SHT_HASH:
     202    case SHT_REL:
     203    case SHT_RELA:
     204    case SHT_DYNSYM:
     205    case SHT_SYMTAB:
     206    case SHT_DYNAMIC:
     207        sec->sh_addralign = 4;
     208        break;
     209    case SHT_STRTAB:
     210        sec->sh_addralign = 1;
     211        break;
     212    default:
     213        sec->sh_addralign =  PTR_SIZE; /* gcc/pcc default alignment */
     214        break;
     215    }
     216
     217    if (sh_flags & SHF_PRIVATE) {
     218        dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
     219    } else {
     220        sec->sh_num = s1->nb_sections;
     221        dynarray_add(&s1->sections, &s1->nb_sections, sec);
     222    }
     223
     224    return sec;
     225}
     226
     227ST_FUNC Section *new_symtab(TCCState *s1,
     228                           const char *symtab_name, int sh_type, int sh_flags,
     229                           const char *strtab_name,
     230                           const char *hash_name, int hash_sh_flags)
     231{
     232    Section *symtab, *strtab, *hash;
     233    int *ptr, nb_buckets;
     234
     235    symtab = new_section(s1, symtab_name, sh_type, sh_flags);
     236    symtab->sh_entsize = sizeof(ElfW(Sym));
     237    strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
     238    put_elf_str(strtab, "");
     239    symtab->link = strtab;
     240    put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
     241
     242    nb_buckets = 1;
     243
     244    hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
     245    hash->sh_entsize = sizeof(int);
     246    symtab->hash = hash;
     247    hash->link = symtab;
     248
     249    ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
     250    ptr[0] = nb_buckets;
     251    ptr[1] = 1;
     252    memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
     253    return symtab;
     254}
     255
     256/* realloc section and set its content to zero */
     257ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
     258{
     259    unsigned long size;
     260    unsigned char *data;
     261
     262    size = sec->data_allocated;
     263    if (size == 0)
     264        size = 1;
     265    while (size < new_size)
     266        size = size * 2;
     267    data = tcc_realloc(sec->data, size);
     268    memset(data + sec->data_allocated, 0, size - sec->data_allocated);
     269    sec->data = data;
     270    sec->data_allocated = size;
     271}
     272
     273/* reserve at least 'size' bytes aligned per 'align' in section
     274   'sec' from current offset, and return the aligned offset */
     275ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
     276{
     277    size_t offset, offset1;
     278
     279    offset = (sec->data_offset + align - 1) & -align;
     280    offset1 = offset + size;
     281    if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
     282        section_realloc(sec, offset1);
     283    sec->data_offset = offset1;
     284    if (align > sec->sh_addralign)
     285        sec->sh_addralign = align;
     286    return offset;
     287}
     288
     289/* reserve at least 'size' bytes in section 'sec' from
     290   sec->data_offset. */
     291ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
     292{
     293    size_t offset = section_add(sec, size, 1);
     294    return sec->data + offset;
     295}
     296
     297/* reserve at least 'size' bytes from section start */
     298ST_FUNC void section_reserve(Section *sec, unsigned long size)
     299{
     300    if (size > sec->data_allocated)
     301        section_realloc(sec, size);
     302    if (size > sec->data_offset)
     303        sec->data_offset = size;
     304}
     305
     306/* return a reference to a section, and create it if it does not
     307   exists */
     308ST_FUNC Section *find_section(TCCState *s1, const char *name)
     309{
     310    Section *sec;
     311    int i;
     312    for(i = 1; i < s1->nb_sections; i++) {
     313        sec = s1->sections[i];
     314        if (!strcmp(name, sec->name))
     315            return sec;
     316    }
     317    /* sections are created as PROGBITS */
     318    return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
     319}
     320
     321/* ------------------------------------------------------------------------- */
    24322
    25323ST_FUNC int put_elf_str(Section *s, const char *sym)
     
    31329    offset = s->data_offset;
    32330    ptr = section_ptr_add(s, len);
    33     memcpy(ptr, sym, len);
     331    memmove(ptr, sym, len);
    34332    return offset;
    35333}
     
    39337{
    40338    unsigned long h = 0, g;
    41    
     339
    42340    while (*name) {
    43341        h = (h << 4) + *name++;
     
    56354    ElfW(Sym) *sym;
    57355    int *ptr, *hash, nb_syms, sym_index, h;
    58     char *strtab;
     356    unsigned char *strtab;
    59357
    60358    strtab = s->link->data;
    61359    nb_syms = s->data_offset / sizeof(ElfW(Sym));
     360
     361    if (!nb_buckets)
     362        nb_buckets = ((int*)s->hash->data)[0];
    62363
    63364    s->hash->data_offset = 0;
     
    92393    ElfW(Sym) *sym;
    93394    Section *hs;
    94    
     395
    95396    sym = section_ptr_add(s, sizeof(ElfW(Sym)));
    96     if (name)
     397    if (name && name[0])
    97398        name_offset = put_elf_str(s->link, name);
    98399    else
     
    111412        ptr = section_ptr_add(hs, sizeof(int));
    112413        base = (int *)hs->data;
    113         /* only add global or weak symbols */
     414        /* only add global or weak symbols. */
    114415        if (ELFW(ST_BIND)(info) != STB_LOCAL) {
    115416            /* add another hashing entry */
    116417            nbuckets = base[0];
    117             h = elf_hash(name) % nbuckets;
     418            h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
    118419            *ptr = base[2 + h];
    119420            base[2 + h] = sym_index;
     
    132433}
    133434
    134 /* find global ELF symbol 'name' and return its index. Return 0 if not
    135    found. */
    136435ST_FUNC int find_elf_sym(Section *s, const char *name)
    137436{
     
    140439    int nbuckets, sym_index, h;
    141440    const char *name1;
    142    
     441
    143442    hs = s->hash;
    144443    if (!hs)
    145444        return 0;
    146445    nbuckets = ((int *)hs->data)[0];
    147     h = elf_hash(name) % nbuckets;
     446    h = elf_hash((unsigned char *) name) % nbuckets;
    148447    sym_index = ((int *)hs->data)[2 + h];
    149448    while (sym_index != 0) {
    150449        sym = &((ElfW(Sym) *)s->data)[sym_index];
    151         name1 = s->link->data + sym->st_name;
     450        name1 = (char *) s->link->data + sym->st_name;
    152451        if (!strcmp(name, name1))
    153452            return sym_index;
     
    179478}
    180479
    181 #ifdef TCC_IS_NATIVE
     480#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
    182481/* return elf symbol value or error */
    183482ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
    184483{
    185     return (void*)get_elf_sym_addr(s, name, 1);
     484    return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
    186485}
    187486#endif
     
    189488/* add an elf symbol : check if it is already defined and patch
    190489   it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
    191 ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
    192                        int info, int other, int sh_num, const char *name)
     490ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
     491                       int info, int other, int shndx, const char *name)
    193492{
    194493    ElfW(Sym) *esym;
     
    199498    sym_type = ELFW(ST_TYPE)(info);
    200499    sym_vis = ELFW(ST_VISIBILITY)(other);
    201        
     500
    202501    if (sym_bind != STB_LOCAL) {
    203502        /* we search global or weak symbols */
     
    206505            goto do_def;
    207506        esym = &((ElfW(Sym) *)s->data)[sym_index];
     507        if (esym->st_value == value && esym->st_size == size && esym->st_info == info
     508            && esym->st_other == other && esym->st_shndx == shndx)
     509            return sym_index;
    208510        if (esym->st_shndx != SHN_UNDEF) {
    209511            esym_bind = ELFW(ST_BIND)(esym->st_info);
     
    221523                             | new_vis;
    222524            other = esym->st_other; /* in case we have to patch esym */
    223             if (sh_num == SHN_UNDEF) {
     525            if (shndx == SHN_UNDEF) {
    224526                /* ignore adding of undefined symbol if the
    225527                   corresponding symbol is already defined */
     
    233535            } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
    234536                /* ignore hidden symbols after */
    235             } else if (esym->st_shndx == SHN_COMMON
    236                     && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) {
    237                 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
    238                    No idea if this is the correct solution ... */
     537            } else if ((esym->st_shndx == SHN_COMMON
     538                            || esym->st_shndx == bss_section->sh_num)
     539                        && (shndx < SHN_LORESERVE
     540                            && shndx != bss_section->sh_num)) {
     541                /* data symbol gets precedence over common/bss */
    239542                goto do_patch;
    240             } else if (s == tcc_state->dynsymtab_section) {
     543            } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
     544                /* data symbol keeps precedence over common/bss */
     545            } else if (s->sh_flags & SHF_DYNSYM) {
    241546                /* we accept that two DLL define the same symbol */
     547            } else if (esym->st_other & ST_ASM_SET) {
     548                /* If the existing symbol came from an asm .set
     549                   we can override.  */
     550                goto do_patch;
    242551            } else {
    243552#if 0
    244553                printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
    245                        sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
     554                       sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
    246555#endif
    247556                tcc_error_noabort("'%s' defined twice", name);
     
    250559        do_patch:
    251560            esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
    252             esym->st_shndx = sh_num;
     561            esym->st_shndx = shndx;
    253562            new_undef_sym = 1;
    254563            esym->st_value = value;
     
    258567    } else {
    259568    do_def:
    260         sym_index = put_elf_sym(s, value, size, 
    261                                 ELFW(ST_INFO)(sym_bind, sym_type), other, 
    262                                 sh_num, name);
     569        sym_index = put_elf_sym(s, value, size,
     570                                ELFW(ST_INFO)(sym_bind, sym_type), other,
     571                                shndx, name);
    263572    }
    264573    return sym_index;
     
    266575
    267576/* put relocation */
    268 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
    269                           int type, int symbol)
     577ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
     578                            int type, int symbol, addr_t addend)
    270579{
    271580    char buf[256];
     
    288597    rel->r_offset = offset;
    289598    rel->r_info = ELFW(R_INFO)(symbol, type);
    290 #ifdef TCC_TARGET_X86_64
    291     rel->r_addend = 0;
    292 #endif
     599#if SHT_RELX == SHT_RELA
     600    rel->r_addend = addend;
     601#else
     602    if (addend)
     603        tcc_error("non-zero addend on REL architecture");
     604#endif
     605}
     606
     607ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
     608                           int type, int symbol)
     609{
     610    put_elf_reloca(symtab, s, offset, type, symbol, 0);
     611}
     612
     613/* Remove relocations for section S->reloc starting at oldrelocoffset
     614   that are to the same place, retaining the last of them.  As side effect
     615   the relocations are sorted.  Possibly reduces the number of relocs.  */
     616ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
     617{
     618    Section *sr = s->reloc;
     619    ElfW_Rel *r, *dest;
     620    ssize_t a;
     621    ElfW(Addr) addr;
     622
     623    if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
     624      return;
     625    /* The relocs we're dealing with are the result of initializer parsing.
     626       So they will be mostly in order and there aren't many of them.
     627       Secondly we need a stable sort (which qsort isn't).  We use
     628       a simple insertion sort.  */
     629    for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
     630        ssize_t i = a - sizeof(*r);
     631        addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
     632        for (; i >= (ssize_t)oldrelocoffset &&
     633               ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
     634            ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
     635            *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
     636            *(ElfW_Rel*)(sr->data + i) = tmp;
     637        }
     638    }
     639
     640    r = (ElfW_Rel*)(sr->data + oldrelocoffset);
     641    dest = r;
     642    for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
     643        if (dest->r_offset != r->r_offset)
     644          dest++;
     645        *dest = *r;
     646    }
     647    sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
    293648}
    294649
     
    312667}
    313668
    314 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, 
     669ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
    315670                        unsigned long value, Section *sec, int sym_index)
    316671{
    317672    put_stabs(str, type, other, desc, value);
    318     put_elf_reloc(symtab_section, stab_section, 
     673    put_elf_reloc(symtab_section, stab_section,
    319674                  stab_section->data_offset - sizeof(unsigned int),
    320675                  R_DATA_32, sym_index);
     
    331686}
    332687
    333 /* In an ELF file symbol table, the local symbols must appear below
    334    the global and weak ones. Since TCC cannot sort it while generating
    335    the code, we must do it after. All the relocation tables are also
    336    modified to take into account the symbol table sorting */
    337 static void sort_syms(TCCState *s1, Section *s)
    338 {
    339     int *old_to_new_syms;
    340     ElfW(Sym) *new_syms;
    341     int nb_syms, i;
    342     ElfW(Sym) *p, *q;
    343     ElfW_Rel *rel, *rel_end;
    344     Section *sr;
    345     int type, sym_index;
    346 
    347     nb_syms = s->data_offset / sizeof(ElfW(Sym));
    348     new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
    349     old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
    350 
    351     /* first pass for local symbols */
    352     p = (ElfW(Sym) *)s->data;
    353     q = new_syms;
    354     for(i = 0; i < nb_syms; i++) {
    355         if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
    356             old_to_new_syms[i] = q - new_syms;
    357             *q++ = *p;
    358         }
    359         p++;
    360     }
    361     /* save the number of local symbols in section header */
    362     s->sh_info = q - new_syms;
    363 
    364     /* then second pass for non local symbols */
    365     p = (ElfW(Sym) *)s->data;
    366     for(i = 0; i < nb_syms; i++) {
    367         if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
    368             old_to_new_syms[i] = q - new_syms;
    369             *q++ = *p;
    370         }
    371         p++;
    372     }
    373    
    374     /* we copy the new symbols to the old */
    375     memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
    376     tcc_free(new_syms);
    377 
    378     /* now we modify all the relocations */
    379     for(i = 1; i < s1->nb_sections; i++) {
    380         sr = s1->sections[i];
    381         if (sr->sh_type == SHT_RELX && sr->link == s) {
    382             rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
    383             for(rel = (ElfW_Rel *)sr->data;
    384                 rel < rel_end;
    385                 rel++) {
    386                 sym_index = ELFW(R_SYM)(rel->r_info);
    387                 type = ELFW(R_TYPE)(rel->r_info);
    388                 sym_index = old_to_new_syms[sym_index];
    389                 rel->r_info = ELFW(R_INFO)(sym_index, type);
    390             }
    391         }
    392     }
    393    
    394     tcc_free(old_to_new_syms);
    395 }
    396 
    397 /* relocate common symbols in the .bss section */
    398 ST_FUNC void relocate_common_syms(void)
    399 {
    400     ElfW(Sym) *sym, *sym_end;
    401     unsigned long offset, align;
    402    
    403     sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
    404     for(sym = (ElfW(Sym) *)symtab_section->data + 1;
    405         sym < sym_end;
    406         sym++) {
    407         if (sym->st_shndx == SHN_COMMON) {
    408             /* align symbol */
    409             align = sym->st_value;
    410             offset = bss_section->data_offset;
    411             offset = (offset + align - 1) & -align;
    412             sym->st_value = offset;
    413             sym->st_shndx = bss_section->sh_num;
    414             offset += sym->st_size;
    415             bss_section->data_offset = offset;
    416         }
    417     }
    418 }
    419 
    420 /* relocate symbol table, resolve undefined symbols if do_resolve is
    421    true and output error if undefined symbol. */
    422 ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
    423 {
    424     ElfW(Sym) *sym, *esym, *sym_end;
    425     int sym_bind, sh_num, sym_index;
    426     const char *name;
    427 
    428     sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
    429     for(sym = (ElfW(Sym) *)symtab_section->data + 1;
    430         sym < sym_end;
    431         sym++) {
    432         sh_num = sym->st_shndx;
    433         if (sh_num == SHN_UNDEF) {
    434             name = strtab_section->data + sym->st_name;
    435             if (do_resolve) {
    436 #if defined TCC_IS_NATIVE && !defined _WIN32
    437                 void *addr;
    438                 name = symtab_section->link->data + sym->st_name;
    439                 addr = resolve_sym(s1, name);
    440                 if (addr) {
    441                     sym->st_value = (addr_t)addr;
    442                     goto found;
    443                 }
    444 #endif
    445             } else if (s1->dynsym) {
    446                 /* if dynamic symbol exist, then use it */
    447                 sym_index = find_elf_sym(s1->dynsym, name);
    448                 if (sym_index) {
    449                     esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
    450                     sym->st_value = esym->st_value;
    451                     goto found;
    452                 }
    453             }
    454             /* XXX: _fp_hw seems to be part of the ABI, so we ignore
    455                it */
    456             if (!strcmp(name, "_fp_hw"))
    457                 goto found;
    458             /* only weak symbols are accepted to be undefined. Their
    459                value is zero */
    460             sym_bind = ELFW(ST_BIND)(sym->st_info);
    461             if (sym_bind == STB_WEAK) {
    462                 sym->st_value = 0;
    463             } else {
    464                 tcc_error_noabort("undefined symbol '%s'", name);
    465             }
    466         } else if (sh_num < SHN_LORESERVE) {
    467             /* add section base */
    468             sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
    469         }
    470     found: ;
    471     }
    472 }
    473 
    474 #ifdef TCC_HAS_RUNTIME_PLTGOT
    475 #ifdef TCC_TARGET_X86_64
    476 #define JMP_TABLE_ENTRY_SIZE 14
    477 static addr_t add_jmp_table(TCCState *s1, addr_t val)
    478 {
    479     char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
    480     s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
    481     /* jmp *0x0(%rip) */
    482     p[0] = 0xff;
    483     p[1] = 0x25;
    484     *(int *)(p + 2) = 0;
    485     *(addr_t *)(p + 6) = val;
    486     return (addr_t)p;
    487 }
    488 
    489 static addr_t add_got_table(TCCState *s1, addr_t val)
    490 {
    491     addr_t *p = (addr_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
    492     s1->runtime_plt_and_got_offset += sizeof(addr_t);
    493     *p = val;
    494     return (addr_t)p;
    495 }
    496 #elif defined TCC_TARGET_ARM
    497 #define JMP_TABLE_ENTRY_SIZE 8
    498 static addr_t add_jmp_table(TCCState *s1, int val)
    499 {
    500     uint32_t *p = (uint32_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
    501     s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
    502     /* ldr pc, [pc, #-4] */
    503     p[0] = 0xE51FF004;
    504     p[1] = val;
    505     return (addr_t)p;
    506 }
    507 #endif
    508 #endif /* def TCC_HAS_RUNTIME_PLTGOT */
    509 
    510 /* relocate a given section (CPU dependent) */
    511 ST_FUNC void relocate_section(TCCState *s1, Section *s)
    512 {
    513     Section *sr;
    514     ElfW_Rel *rel, *rel_end, *qrel;
    515     ElfW(Sym) *sym;
    516     int type, sym_index;
    517     unsigned char *ptr;
    518     addr_t val, addr;
    519 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
    520     int esym_index;
    521 #endif
    522 
    523     sr = s->reloc;
    524     rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
    525     qrel = (ElfW_Rel *)sr->data;
    526     for(rel = qrel;
    527         rel < rel_end;
    528         rel++) {
    529         ptr = s->data + rel->r_offset;
    530 
    531         sym_index = ELFW(R_SYM)(rel->r_info);
    532         sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    533         val = sym->st_value;
    534 #ifdef TCC_TARGET_X86_64
    535         val += rel->r_addend;
    536 #endif
    537         type = ELFW(R_TYPE)(rel->r_info);
    538         addr = s->sh_addr + rel->r_offset;
    539 
    540         /* CPU specific */
    541         switch(type) {
    542 #if defined(TCC_TARGET_I386)
    543         case R_386_32:
    544             if (s1->output_type == TCC_OUTPUT_DLL) {
    545                 esym_index = s1->symtab_to_dynsym[sym_index];
    546                 qrel->r_offset = rel->r_offset;
    547                 if (esym_index) {
    548                     qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
    549                     qrel++;
    550                     break;
    551                 } else {
    552                     qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
    553                     qrel++;
    554                 }
    555             }
    556             *(int *)ptr += val;
    557             break;
    558         case R_386_PC32:
    559             if (s1->output_type == TCC_OUTPUT_DLL) {
    560                 /* DLL relocation */
    561                 esym_index = s1->symtab_to_dynsym[sym_index];
    562                 if (esym_index) {
    563                     qrel->r_offset = rel->r_offset;
    564                     qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
    565                     qrel++;
    566                     break;
    567                 }
    568             }
    569             *(int *)ptr += val - addr;
    570             break;
    571         case R_386_PLT32:
    572             *(int *)ptr += val - addr;
    573             break;
    574         case R_386_GLOB_DAT:
    575         case R_386_JMP_SLOT:
    576             *(int *)ptr = val;
    577             break;
    578         case R_386_GOTPC:
    579             *(int *)ptr += s1->got->sh_addr - addr;
    580             break;
    581         case R_386_GOTOFF:
    582             *(int *)ptr += val - s1->got->sh_addr;
    583             break;
    584         case R_386_GOT32:
    585             /* we load the got offset */
    586             *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
    587             break;
    588         case R_386_16:
    589             if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
    590             output_file:
    591             tcc_error("can only produce 16-bit binary files");
    592             }
    593             *(short *)ptr += val;
    594             break;
    595         case R_386_PC16:
    596             if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
    597             goto output_file;
    598             *(short *)ptr += val - addr;
    599             break;
    600 #elif defined(TCC_TARGET_ARM)
    601         case R_ARM_PC24:
    602         case R_ARM_CALL:
    603         case R_ARM_JUMP24:
    604         case R_ARM_PLT32:
    605             {
    606                 int x, is_thumb, is_call, h, blx_avail;
    607                 x = (*(int *)ptr)&0xffffff;
    608                 (*(int *)ptr) &= 0xff000000;
    609                 if (x & 0x800000)
    610                     x -= 0x1000000;
    611                 x <<= 2;
    612                 blx_avail = (TCC_ARM_VERSION >= 5);
    613                 is_thumb = val & 1;
    614                 is_call = (type == R_ARM_CALL);
    615                 x += val - addr;
    616                 h = x & 2;
    617 #ifdef TCC_HAS_RUNTIME_PLTGOT
    618                 if (s1->output_type == TCC_OUTPUT_MEMORY) {
    619                     if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
    620                         if (!(x & 3) || !blx_avail || !is_call) {
    621                             x += add_jmp_table(s1, val) - val; /* add veneer */
    622                             is_thumb = 0; /* Veneer uses ARM instructions */
    623                         }
    624                 }
    625 #endif
    626                 if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
    627                     if (!(x & 3) || !blx_avail || !is_call)
    628                         tcc_error("can't relocate value at %x",addr);
    629                 x >>= 2;
    630                 x &= 0xffffff;
    631                 /* Only reached if blx is avail and it is a call */
    632                 if (is_thumb) {
    633                     x |= h << 24;
    634                     (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
    635                 }
    636                 (*(int *)ptr) |= x;
    637             }
    638             break;
    639         /* Since these relocations only concern Thumb-2 and blx instruction was
    640            introduced before Thumb-2, we can assume blx is available and not
    641            guard its use */
    642         case R_ARM_THM_CALL:
    643         case R_ARM_THM_JUMP24:
    644             {
    645                 int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
    646                 int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
    647                 Section *plt;
    648 
    649                 /* weak reference */
    650                 if (sym->st_shndx == SHN_UNDEF &&
    651                     ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
    652                     break;
    653 
    654                 /* Get initial offset */
    655                 hi = (*(uint16_t *)ptr);
    656                 lo = (*(uint16_t *)(ptr+2));
    657                 s = (hi >> 10) & 1;
    658                 j1 = (lo >> 13) & 1;
    659                 j2 = (lo >> 11) & 1;
    660                 i1 = (j1 ^ s) ^ 1;
    661                 i2 = (j2 ^ s) ^ 1;
    662                 imm10 = hi & 0x3ff;
    663                 imm11 = lo & 0x7ff;
    664                 x = (s << 24) | (i1 << 23) | (i2 << 22) |
    665                     (imm10 << 12) | (imm11 << 1);
    666                 if (x & 0x01000000)
    667                     x -= 0x02000000;
    668 
    669                 /* Relocation infos */
    670                 to_thumb = val & 1;
    671                 plt = s1->plt;
    672                 to_plt = (val >= plt->sh_addr) &&
    673                          (val < plt->sh_addr + plt->data_offset);
    674                 is_call = (type == R_ARM_THM_CALL);
    675 
    676                 /* Compute final offset */
    677                 if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */
    678                     x -= 4;
    679                 x += val - addr;
    680                 if (!to_thumb && is_call) {
    681                     blx_bit = 0; /* bl -> blx */
    682                     x = (x + 3) & -4; /* Compute offset from aligned PC */
    683                 }
    684 
    685                 /* Check that relocation is possible
    686                    * offset must not be out of range
    687                    * if target is to be entered in arm mode:
    688                      - bit 1 must not set
    689                      - instruction must be a call (bl) or a jump to PLT */
    690                 if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
    691                     if (to_thumb || (val & 2) || (!is_call && !to_plt))
    692                         tcc_error("can't relocate value at %x",addr);
    693 
    694                 /* Compute and store final offset */
    695                 s = (x >> 24) & 1;
    696                 i1 = (x >> 23) & 1;
    697                 i2 = (x >> 22) & 1;
    698                 j1 = s ^ (i1 ^ 1);
    699                 j2 = s ^ (i2 ^ 1);
    700                 imm10 = (x >> 12) & 0x3ff;
    701                 imm11 = (x >> 1) & 0x7ff;
    702                 (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) |
    703                                      (s << 10) | imm10);
    704                 (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) |
    705                                 (j1 << 13) | blx_bit | (j2 << 11) |
    706                                 imm11);
    707             }
    708             break;
    709         case R_ARM_MOVT_ABS:
    710         case R_ARM_MOVW_ABS_NC:
    711             {
    712                 int x, imm4, imm12;
    713                 if (type == R_ARM_MOVT_ABS)
    714                     val >>= 16;
    715                 imm12 = val & 0xfff;
    716                 imm4 = (val >> 12) & 0xf;
    717                 x = (imm4 << 16) | imm12;
    718                 if (type == R_ARM_THM_MOVT_ABS)
    719                     *(int *)ptr |= x;
    720                 else
    721                     *(int *)ptr += x;
    722         }
    723             break;
    724         case R_ARM_THM_MOVT_ABS:
    725         case R_ARM_THM_MOVW_ABS_NC:
    726             {
    727                 int x, i, imm4, imm3, imm8;
    728                 if (type == R_ARM_THM_MOVT_ABS)
    729                     val >>= 16;
    730                 imm8 = val & 0xff;
    731                 imm3 = (val >> 8) & 0x7;
    732                 i = (val >> 11) & 1;
    733                 imm4 = (val >> 12) & 0xf;
    734                 x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4;
    735                 if (type == R_ARM_THM_MOVT_ABS)
    736                     *(int *)ptr |= x;
    737                 else
    738                     *(int *)ptr += x;
    739         }
    740             break;
    741         case R_ARM_PREL31:
    742             {
    743                 int x;
    744                 x = (*(int *)ptr) & 0x7fffffff;
    745                 (*(int *)ptr) &= 0x80000000;
    746                 x = (x * 2) / 2;
    747                 x += val - addr;
    748                 if((x^(x>>1))&0x40000000)
    749                     tcc_error("can't relocate value at %x",addr);
    750                 (*(int *)ptr) |= x & 0x7fffffff;
    751             }
    752         case R_ARM_ABS32:
    753             *(int *)ptr += val;
    754             break;
    755         case R_ARM_REL32:
    756             *(int *)ptr += val - addr;
    757             break;
    758         case R_ARM_BASE_PREL:
    759             *(int *)ptr += s1->got->sh_addr - addr;
    760             break;
    761         case R_ARM_GOTOFF32:
    762             *(int *)ptr += val - s1->got->sh_addr;
    763             break;
    764         case R_ARM_GOT_BREL:
    765             /* we load the got offset */
    766             *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
    767             break;
    768         case R_ARM_COPY:
    769             break;
    770         case R_ARM_V4BX:
    771             /* trade Thumb support for ARMv4 support */
    772             if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10)
    773                 *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
    774             break;
    775         default:
    776             fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
    777                 type, (unsigned)addr, ptr, (unsigned)val);
    778             break;
    779 #elif defined(TCC_TARGET_C67)
    780         case R_C60_32:
    781             *(int *)ptr += val;
    782             break;
    783         case R_C60LO16:
    784             {
    785                 uint32_t orig;
    786                
    787                 /* put the low 16 bits of the absolute address */
    788                 // add to what is already there
    789                
    790                 orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
    791                 orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
    792                
    793                 //patch both at once - assumes always in pairs Low - High
    794                
    795                 *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |  (((val+orig)      & 0xffff) << 7);
    796                 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
    797             }
    798             break;
    799         case R_C60HI16:
    800             break;
    801         default:
    802             fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
    803                 type, (unsigned)addr, ptr, (unsigned)val);
    804             break;
    805 #elif defined(TCC_TARGET_X86_64)
    806         case R_X86_64_64:
    807             if (s1->output_type == TCC_OUTPUT_DLL) {
    808                 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
    809                 qrel->r_addend = *(long long *)ptr + val;
    810                 qrel++;
    811             }
    812             *(long long *)ptr += val;
    813             break;
    814         case R_X86_64_32:
    815         case R_X86_64_32S:
    816             if (s1->output_type == TCC_OUTPUT_DLL) {
    817                 /* XXX: this logic may depend on TCC's codegen
    818                    now TCC uses R_X86_64_32 even for a 64bit pointer */
    819                 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
    820                 qrel->r_addend = *(int *)ptr + val;
    821                 qrel++;
    822             }
    823             *(int *)ptr += val;
    824             break;
    825 
    826         case R_X86_64_PC32:
    827             if (s1->output_type == TCC_OUTPUT_DLL) {
    828                 /* DLL relocation */
    829                 esym_index = s1->symtab_to_dynsym[sym_index];
    830                 if (esym_index) {
    831                     qrel->r_offset = rel->r_offset;
    832                     qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
    833                     qrel->r_addend = *(int *)ptr;
    834                     qrel++;
    835                     break;
    836                 }
    837             }
    838             /* fall through */
    839         case R_X86_64_PLT32: {
    840             long long diff;
    841             diff = (long long)val - addr;
    842             if (diff <= -2147483647 || diff > 2147483647) {
    843 #ifdef TCC_HAS_RUNTIME_PLTGOT
    844                 /* XXX: naive support for over 32bit jump */
    845                 if (s1->output_type == TCC_OUTPUT_MEMORY) {
    846                     val = (add_jmp_table(s1, val - rel->r_addend) +
    847                            rel->r_addend);
    848                     diff = val - addr;
    849                 }
    850 #endif
    851                 if (diff <= -2147483647 || diff > 2147483647) {
    852                     tcc_error("internal error: relocation failed");
    853                 }
    854             }
    855             *(int *)ptr += diff;
    856         }
    857             break;
    858         case R_X86_64_GLOB_DAT:
    859         case R_X86_64_JUMP_SLOT:
    860             /* They don't need addend */
    861             *(int *)ptr = val - rel->r_addend;
    862             break;
    863         case R_X86_64_GOTPCREL:
    864 #ifdef TCC_HAS_RUNTIME_PLTGOT
    865             if (s1->output_type == TCC_OUTPUT_MEMORY) {
    866                 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
    867                 *(int *)ptr += val - addr;
    868                 break;
    869             }
    870 #endif
    871             *(int *)ptr += (s1->got->sh_addr - addr +
    872                             s1->sym_attrs[sym_index].got_offset - 4);
    873             break;
    874         case R_X86_64_GOTTPOFF:
    875             *(int *)ptr += val - s1->got->sh_addr;
    876             break;
    877         case R_X86_64_GOT32:
    878             /* we load the got offset */
    879             *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
    880             break;
    881 #elif  defined(TCC_TARGET_IL)
    882 #else
    883 #error unsupported processor
    884 #endif
    885         }
    886     }
    887     /* if the relocation is allocated, we change its symbol table */
    888     if (sr->sh_flags & SHF_ALLOC)
    889         sr->link = s1->dynsym;
    890 }
    891 
    892 /* relocate relocation table in 'sr' */
    893 static void relocate_rel(TCCState *s1, Section *sr)
    894 {
    895     Section *s;
    896     ElfW_Rel *rel, *rel_end;
    897    
    898     s = s1->sections[sr->sh_info];
    899     rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
    900     for(rel = (ElfW_Rel *)sr->data;
    901         rel < rel_end;
    902         rel++) {
    903         rel->r_offset += s->sh_addr;
    904     }
    905 }
    906 
    907 /* count the number of dynamic relocations so that we can reserve
    908    their space */
    909 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
    910 {
    911     ElfW_Rel *rel, *rel_end;
    912     int sym_index, esym_index, type, count;
    913 
    914     count = 0;
    915     rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
    916     for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
    917         sym_index = ELFW(R_SYM)(rel->r_info);
    918         type = ELFW(R_TYPE)(rel->r_info);
    919         switch(type) {
    920 #if defined(TCC_TARGET_I386)
    921         case R_386_32:
    922 #elif defined(TCC_TARGET_X86_64)
    923         case R_X86_64_32:
    924         case R_X86_64_32S:
    925         case R_X86_64_64:
    926 #endif
    927             count++;
    928             break;
    929 #if defined(TCC_TARGET_I386)
    930         case R_386_PC32:
    931 #elif defined(TCC_TARGET_X86_64)
    932         case R_X86_64_PC32:
    933 #endif
    934             esym_index = s1->symtab_to_dynsym[sym_index];
    935             if (esym_index)
    936                 count++;
    937             break;
    938         default:
    939             break;
    940         }
    941     }
    942     if (count) {
    943         /* allocate the section */
    944         sr->sh_flags |= SHF_ALLOC;
    945         sr->sh_size = count * sizeof(ElfW_Rel);
    946     }
    947     return count;
    948 }
    949 
    950 static struct sym_attr *alloc_sym_attr(TCCState *s1, int index)
     688ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
    951689{
    952690    int n;
     
    954692
    955693    if (index >= s1->nb_sym_attrs) {
     694        if (!alloc)
     695            return s1->sym_attrs;
    956696        /* find immediately bigger power of 2 and reallocate array */
    957697        n = 1;
     
    967707}
    968708
    969 /* XXX: suppress that */
    970 static void put32(unsigned char *p, uint32_t val)
    971 {
    972     p[0] = val;
    973     p[1] = val >> 8;
    974     p[2] = val >> 16;
    975     p[3] = val >> 24;
    976 }
    977 
    978 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
    979     defined(TCC_TARGET_X86_64)
    980 static uint32_t get32(unsigned char *p)
    981 {
    982     return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
    983 }
    984 #endif
     709/* Browse each elem of type <type> in section <sec> starting at elem <startoff>
     710   using variable <elem> */
     711#define for_each_elem(sec, startoff, elem, type) \
     712    for (elem = (type *) sec->data + startoff; \
     713         elem < (type *) (sec->data + sec->data_offset); elem++)
     714
     715/* In an ELF file symbol table, the local symbols must appear below
     716   the global and weak ones. Since TCC cannot sort it while generating
     717   the code, we must do it after. All the relocation tables are also
     718   modified to take into account the symbol table sorting */
     719static void sort_syms(TCCState *s1, Section *s)
     720{
     721    int *old_to_new_syms;
     722    ElfW(Sym) *new_syms;
     723    int nb_syms, i;
     724    ElfW(Sym) *p, *q;
     725    ElfW_Rel *rel;
     726    Section *sr;
     727    int type, sym_index;
     728
     729    nb_syms = s->data_offset / sizeof(ElfW(Sym));
     730    new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
     731    old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
     732
     733    /* first pass for local symbols */
     734    p = (ElfW(Sym) *)s->data;
     735    q = new_syms;
     736    for(i = 0; i < nb_syms; i++) {
     737        if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
     738            old_to_new_syms[i] = q - new_syms;
     739            *q++ = *p;
     740        }
     741        p++;
     742    }
     743    /* save the number of local symbols in section header */
     744    if( s->sh_size )    /* this 'if' makes IDA happy */
     745        s->sh_info = q - new_syms;
     746
     747    /* then second pass for non local symbols */
     748    p = (ElfW(Sym) *)s->data;
     749    for(i = 0; i < nb_syms; i++) {
     750        if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
     751            old_to_new_syms[i] = q - new_syms;
     752            *q++ = *p;
     753        }
     754        p++;
     755    }
     756
     757    /* we copy the new symbols to the old */
     758    memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
     759    tcc_free(new_syms);
     760
     761    /* now we modify all the relocations */
     762    for(i = 1; i < s1->nb_sections; i++) {
     763        sr = s1->sections[i];
     764        if (sr->sh_type == SHT_RELX && sr->link == s) {
     765            for_each_elem(sr, 0, rel, ElfW_Rel) {
     766                sym_index = ELFW(R_SYM)(rel->r_info);
     767                type = ELFW(R_TYPE)(rel->r_info);
     768                sym_index = old_to_new_syms[sym_index];
     769                rel->r_info = ELFW(R_INFO)(sym_index, type);
     770            }
     771        }
     772    }
     773
     774    tcc_free(old_to_new_syms);
     775}
     776
     777/* relocate symbol table, resolve undefined symbols if do_resolve is
     778   true and output error if undefined symbol. */
     779ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
     780{
     781    ElfW(Sym) *sym;
     782    int sym_bind, sh_num;
     783    const char *name;
     784
     785    for_each_elem(symtab, 1, sym, ElfW(Sym)) {
     786        sh_num = sym->st_shndx;
     787        if (sh_num == SHN_UNDEF) {
     788            name = (char *) s1->symtab->link->data + sym->st_name;
     789            /* Use ld.so to resolve symbol for us (for tcc -run) */
     790            if (do_resolve) {
     791#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
     792                void *addr = dlsym(RTLD_DEFAULT, name);
     793                if (addr) {
     794                    sym->st_value = (addr_t) addr;
     795#ifdef DEBUG_RELOC
     796                    printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
     797#endif
     798                    goto found;
     799                }
     800#endif
     801            /* if dynamic symbol exist, it will be used in relocate_section */
     802            } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
     803                goto found;
     804            /* XXX: _fp_hw seems to be part of the ABI, so we ignore
     805               it */
     806            if (!strcmp(name, "_fp_hw"))
     807                goto found;
     808            /* only weak symbols are accepted to be undefined. Their
     809               value is zero */
     810            sym_bind = ELFW(ST_BIND)(sym->st_info);
     811            if (sym_bind == STB_WEAK)
     812                sym->st_value = 0;
     813            else
     814                tcc_error_noabort("undefined symbol '%s'", name);
     815        } else if (sh_num < SHN_LORESERVE) {
     816            /* add section base */
     817            sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
     818        }
     819    found: ;
     820    }
     821}
     822
     823/* relocate a given section (CPU dependent) by applying the relocations
     824   in the associated relocation section */
     825ST_FUNC void relocate_section(TCCState *s1, Section *s)
     826{
     827    Section *sr = s->reloc;
     828    ElfW_Rel *rel;
     829    ElfW(Sym) *sym;
     830    int type, sym_index;
     831    unsigned char *ptr;
     832    addr_t tgt, addr;
     833
     834    relocate_init(sr);
     835
     836    for_each_elem(sr, 0, rel, ElfW_Rel) {
     837        ptr = s->data + rel->r_offset;
     838        sym_index = ELFW(R_SYM)(rel->r_info);
     839        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
     840        type = ELFW(R_TYPE)(rel->r_info);
     841        tgt = sym->st_value;
     842#if SHT_RELX == SHT_RELA
     843        tgt += rel->r_addend;
     844#endif
     845        addr = s->sh_addr + rel->r_offset;
     846        relocate(s1, rel, type, ptr, addr, tgt);
     847    }
     848    /* if the relocation is allocated, we change its symbol table */
     849    if (sr->sh_flags & SHF_ALLOC)
     850        sr->link = s1->dynsym;
     851}
     852
     853/* relocate relocation table in 'sr' */
     854static void relocate_rel(TCCState *s1, Section *sr)
     855{
     856    Section *s;
     857    ElfW_Rel *rel;
     858
     859    s = s1->sections[sr->sh_info];
     860    for_each_elem(sr, 0, rel, ElfW_Rel)
     861        rel->r_offset += s->sh_addr;
     862}
     863
     864/* count the number of dynamic relocations so that we can reserve
     865   their space */
     866static int prepare_dynamic_rel(TCCState *s1, Section *sr)
     867{
     868    ElfW_Rel *rel;
     869    int sym_index, type, count;
     870
     871    count = 0;
     872    for_each_elem(sr, 0, rel, ElfW_Rel) {
     873        sym_index = ELFW(R_SYM)(rel->r_info);
     874        type = ELFW(R_TYPE)(rel->r_info);
     875        switch(type) {
     876#if defined(TCC_TARGET_I386)
     877        case R_386_32:
     878            if (!get_sym_attr(s1, sym_index, 0)->dyn_index
     879                && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
     880                /* don't fixup unresolved (weak) symbols */
     881                rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
     882                break;
     883            }
     884#elif defined(TCC_TARGET_X86_64)
     885        case R_X86_64_32:
     886        case R_X86_64_32S:
     887        case R_X86_64_64:
     888#endif
     889            count++;
     890            break;
     891#if defined(TCC_TARGET_I386)
     892        case R_386_PC32:
     893#elif defined(TCC_TARGET_X86_64)
     894        case R_X86_64_PC32:
     895#endif
     896            if (get_sym_attr(s1, sym_index, 0)->dyn_index)
     897                count++;
     898            break;
     899        default:
     900            break;
     901        }
     902    }
     903    if (count) {
     904        /* allocate the section */
     905        sr->sh_flags |= SHF_ALLOC;
     906        sr->sh_size = count * sizeof(ElfW_Rel);
     907    }
     908    return count;
     909}
    985910
    986911static void build_got(TCCState *s1)
    987912{
    988     unsigned char *ptr;
    989 
    990913    /* if no got, then create it */
    991914    s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
    992915    s1->got->sh_entsize = 4;
    993     add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
     916    set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
    994917                0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
    995     ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
    996 #if PTR_SIZE == 4
    997     /* keep space for _DYNAMIC pointer, if present */
    998     put32(ptr, 0);
    999     /* two dummy got entries */
    1000     put32(ptr + 4, 0);
    1001     put32(ptr + 8, 0);
    1002 #else
    1003     /* keep space for _DYNAMIC pointer, if present */
    1004     put32(ptr, 0);
    1005     put32(ptr + 4, 0);
    1006     /* two dummy got entries */
    1007     put32(ptr + 8, 0);
    1008     put32(ptr + 12, 0);
    1009     put32(ptr + 16, 0);
    1010     put32(ptr + 20, 0);
    1011 #endif
    1012 }
    1013 
    1014 /* put a got entry corresponding to a symbol in symtab_section. 'size'
    1015    and 'info' can be modifed if more precise info comes from the DLL */
    1016 static void put_got_entry(TCCState *s1,
    1017                           int reloc_type, unsigned long size, int info,
    1018                           int sym_index)
    1019 {
    1020     int index;
     918    /* keep space for _DYNAMIC pointer and two dummy got entries */
     919    section_ptr_add(s1->got, 3 * PTR_SIZE);
     920}
     921
     922/* Create a GOT and (for function call) a PLT entry corresponding to a symbol
     923   in s1->symtab. When creating the dynamic symbol table entry for the GOT
     924   relocation, use 'size' and 'info' for the corresponding symbol metadata.
     925   Returns the offset of the GOT or (if any) PLT entry. */
     926static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
     927                                       unsigned long size,
     928                                       int info, int sym_index)
     929{
     930    int need_plt_entry;
    1021931    const char *name;
    1022932    ElfW(Sym) *sym;
    1023     unsigned long offset;
    1024     int *ptr;
    1025 
    1026     if (!s1->got)
    1027         build_got(s1);
    1028 
    1029     /* if a got entry already exists for that symbol, no need to add one */
    1030     if (sym_index < s1->nb_sym_attrs &&
    1031         s1->sym_attrs[sym_index].got_offset)
    1032         return;
    1033 
    1034     alloc_sym_attr(s1, sym_index)->got_offset = s1->got->data_offset;
     933    struct sym_attr *attr;
     934    unsigned got_offset;
     935    char plt_name[100];
     936    int len;
     937
     938    need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
     939    attr = get_sym_attr(s1, sym_index, 1);
     940
     941    /* In case a function is both called and its address taken 2 GOT entries
     942       are created, one for taking the address (GOT) and the other for the PLT
     943       entry (PLTGOT).  */
     944    if (need_plt_entry ? attr->plt_offset : attr->got_offset)
     945        return attr;
     946
     947    /* create the GOT entry */
     948    got_offset = s1->got->data_offset;
     949    section_ptr_add(s1->got, PTR_SIZE);
     950
     951    /* Create the GOT relocation that will insert the address of the object or
     952       function of interest in the GOT entry. This is a static relocation for
     953       memory output (dlsym will give us the address of symbols) and dynamic
     954       relocation otherwise (executable and DLLs). The relocation should be
     955       done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
     956       associated to a PLT entry) but is currently done at load time for an
     957       unknown reason. */
     958
     959    sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
     960    name = (char *) symtab_section->link->data + sym->st_name;
    1035961
    1036962    if (s1->dynsym) {
    1037         sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    1038         name = symtab_section->link->data + sym->st_name;
    1039         offset = sym->st_value;
    1040 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
    1041         if (reloc_type ==
    1042 #ifdef TCC_TARGET_X86_64
    1043             R_X86_64_JUMP_SLOT
    1044 #else
    1045             R_386_JMP_SLOT
    1046 #endif
    1047             ) {
    1048             Section *plt;
    1049             uint8_t *p;
    1050             int modrm;
    1051 
    1052 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
    1053             modrm = 0x25;
    1054 #else
    1055             /* if we build a DLL, we add a %ebx offset */
    1056             if (s1->output_type == TCC_OUTPUT_DLL)
    1057                 modrm = 0xa3;
    1058             else
    1059                 modrm = 0x25;
    1060 #endif
    1061 
    1062             /* add a PLT entry */
    1063             plt = s1->plt;
    1064             if (plt->data_offset == 0) {
    1065                 /* first plt entry */
    1066                 p = section_ptr_add(plt, 16);
    1067                 p[0] = 0xff; /* pushl got + PTR_SIZE */
    1068                 p[1] = modrm + 0x10;
    1069                 put32(p + 2, PTR_SIZE);
    1070                 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
    1071                 p[7] = modrm;
    1072                 put32(p + 8, PTR_SIZE * 2);
    1073             }
    1074 
    1075             p = section_ptr_add(plt, 16);
    1076             p[0] = 0xff; /* jmp *(got + x) */
    1077             p[1] = modrm;
    1078             put32(p + 2, s1->got->data_offset);
    1079             p[6] = 0x68; /* push $xxx */
    1080             put32(p + 7, (plt->data_offset - 32) >> 1);
    1081             p[11] = 0xe9; /* jmp plt_start */
    1082             put32(p + 12, -(plt->data_offset));
    1083 
    1084             /* the symbol is modified so that it will be relocated to
    1085                the PLT */
    1086 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
    1087             if (s1->output_type == TCC_OUTPUT_EXE)
    1088 #endif
    1089                 offset = plt->data_offset - 16;
    1090         }
    1091 #elif defined(TCC_TARGET_ARM)
    1092         if (reloc_type == R_ARM_JUMP_SLOT) {
    1093             Section *plt;
    1094             uint8_t *p;
    1095            
    1096             /* if we build a DLL, we add a %ebx offset */
    1097             if (s1->output_type == TCC_OUTPUT_DLL)
    1098                 tcc_error("DLLs unimplemented!");
    1099 
    1100             /* add a PLT entry */
    1101             plt = s1->plt;
    1102             if (plt->data_offset == 0) {
    1103                 /* first plt entry */
    1104                 p = section_ptr_add(plt, 16);
    1105                 put32(p     , 0xe52de004);
    1106                 put32(p +  4, 0xe59fe010);
    1107                 put32(p +  8, 0xe08fe00e);
    1108                 put32(p + 12, 0xe5bef008);
    1109             }
    1110 
    1111             if (s1->sym_attrs[sym_index].plt_thumb_stub) {
    1112                 p = section_ptr_add(plt, 20);
    1113                 put32(p  , 0x4778); // bx pc
    1114                 put32(p+2, 0x46c0); // nop
    1115                 p += 4;
    1116             } else
    1117                 p = section_ptr_add(plt, 16);
    1118             put32(p  , 0xe59fc004); // ldr ip, [pc, #4] // offset in GOT
    1119             put32(p+4, 0xe08fc00c); // add ip, pc, ip // absolute address or offset
    1120             put32(p+8, 0xe59cf000); // ldr pc, [ip] // load absolute address or load offset
    1121             put32(p+12, s1->got->data_offset);
    1122 
    1123             /* the symbol is modified so that it will be relocated to
    1124                the PLT */
    1125             if (s1->output_type == TCC_OUTPUT_EXE)
    1126                 offset = plt->data_offset - 16;
    1127         }
    1128 #elif defined(TCC_TARGET_C67)
    1129         tcc_error("C67 got not implemented");
    1130 #elif  defined(TCC_TARGET_IL)
    1131         tcc_error("IL got not implemented");
    1132 #else
    1133 #error unsupported CPU
    1134 #endif
    1135         index = put_elf_sym(s1->dynsym, offset,
    1136                             size, info, 0, sym->st_shndx, name);
    1137         /* put a got entry */
    1138         put_elf_reloc(s1->dynsym, s1->got,
    1139                       s1->got->data_offset,
    1140                       reloc_type, index);
    1141     }
    1142     ptr = section_ptr_add(s1->got, PTR_SIZE);
    1143     *ptr = 0;
     963        if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
     964            /* Hack alarm.  We don't want to emit dynamic symbols
     965               and symbol based relocs for STB_LOCAL symbols, but rather
     966               want to resolve them directly.  At this point the symbol
     967               values aren't final yet, so we must defer this.  We will later
     968               have to create a RELATIVE reloc anyway, so we misuse the
     969               relocation slot to smuggle the symbol reference until
     970               fill_local_got_entries.  Not that the sym_index is
     971               relative to symtab_section, not s1->dynsym!  Nevertheless
     972               we use s1->dyn_sym so that if this is the first call
     973               that got->reloc is correctly created.  Also note that
     974               RELATIVE relocs are not normally created for the .got,
     975               so the types serves as a marker for later (and is retained
     976               also for the final output, which is okay because then the
     977               got is just normal data).  */
     978            put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
     979                          sym_index);
     980        } else {
     981            if (0 == attr->dyn_index)
     982                attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value, size,
     983                                              info, 0, sym->st_shndx, name);
     984            put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
     985                          attr->dyn_index);
     986        }
     987    } else {
     988        put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
     989                      sym_index);
     990    }
     991
     992    if (need_plt_entry) {
     993        if (!s1->plt) {
     994            s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
     995                                  SHF_ALLOC | SHF_EXECINSTR);
     996            s1->plt->sh_entsize = 4;
     997        }
     998
     999        attr->plt_offset = create_plt_entry(s1, got_offset, attr);
     1000
     1001        /* create a symbol 'sym@plt' for the PLT jump vector */
     1002        len = strlen(name);
     1003        if (len > sizeof plt_name - 5)
     1004            len = sizeof plt_name - 5;
     1005        memcpy(plt_name, name, len);
     1006        strcpy(plt_name + len, "@plt");
     1007        attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
     1008            ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
     1009
     1010    } else {
     1011        attr->got_offset = got_offset;
     1012    }
     1013
     1014    return attr;
    11441015}
    11451016
     
    11481019{
    11491020    Section *s;
    1150     ElfW_Rel *rel, *rel_end;
     1021    ElfW_Rel *rel;
    11511022    ElfW(Sym) *sym;
    1152     int i, type, reloc_type, sym_index;
     1023    int i, type, gotplt_entry, reloc_type, sym_index;
     1024    struct sym_attr *attr;
    11531025
    11541026    for(i = 1; i < s1->nb_sections; i++) {
     
    11591031        if (s->link != symtab_section)
    11601032            continue;
    1161         rel_end = (ElfW_Rel *)(s->data + s->data_offset);
    1162         for(rel = (ElfW_Rel *)s->data;
    1163             rel < rel_end;
    1164             rel++) {
     1033        for_each_elem(s, 0, rel, ElfW_Rel) {
    11651034            type = ELFW(R_TYPE)(rel->r_info);
    1166             switch(type) {
    1167 #if defined(TCC_TARGET_I386)
    1168             case R_386_GOT32:
    1169             case R_386_GOTOFF:
    1170             case R_386_GOTPC:
    1171             case R_386_PLT32:
    1172                 if (!s1->got)
    1173                     build_got(s1);
    1174                 if (type == R_386_GOT32 || type == R_386_PLT32) {
    1175                     sym_index = ELFW(R_SYM)(rel->r_info);
    1176                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    1177                     /* look at the symbol got offset. If none, then add one */
    1178                     if (type == R_386_GOT32)
    1179                         reloc_type = R_386_GLOB_DAT;
    1180                     else
    1181                         reloc_type = R_386_JMP_SLOT;
    1182                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
    1183                                   sym_index);
    1184                 }
    1185                 break;
    1186 #elif defined(TCC_TARGET_ARM)
    1187             case R_ARM_GOT_BREL:
    1188             case R_ARM_GOTOFF32:
    1189             case R_ARM_BASE_PREL:
    1190             case R_ARM_PLT32:
    1191                 if (!s1->got)
    1192                     build_got(s1);
    1193                 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
    1194                     sym_index = ELFW(R_SYM)(rel->r_info);
    1195                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    1196                     /* look at the symbol got offset. If none, then add one */
    1197                     if (type == R_ARM_GOT_BREL)
    1198                         reloc_type = R_ARM_GLOB_DAT;
    1199                     else
    1200                         reloc_type = R_ARM_JUMP_SLOT;
    1201                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
    1202                                   sym_index);
    1203                 }
    1204                 break;
    1205 #elif defined(TCC_TARGET_C67)
    1206             case R_C60_GOT32:
    1207             case R_C60_GOTOFF:
    1208             case R_C60_GOTPC:
    1209             case R_C60_PLT32:
    1210                 if (!s1->got)
    1211                     build_got(s1);
    1212                 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
    1213                     sym_index = ELFW(R_SYM)(rel->r_info);
    1214                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    1215                     /* look at the symbol got offset. If none, then add one */
    1216                     if (type == R_C60_GOT32)
    1217                         reloc_type = R_C60_GLOB_DAT;
    1218                     else
    1219                         reloc_type = R_C60_JMP_SLOT;
    1220                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
    1221                                   sym_index);
    1222                 }
    1223                 break;
    1224 #elif defined(TCC_TARGET_X86_64)
    1225             case R_X86_64_GOT32:
    1226             case R_X86_64_GOTTPOFF:
    1227             case R_X86_64_GOTPCREL:
    1228             case R_X86_64_PLT32:
    1229                 if (!s1->got)
    1230                     build_got(s1);
    1231                 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
    1232                     type == R_X86_64_PLT32) {
    1233                     sym_index = ELFW(R_SYM)(rel->r_info);
    1234                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    1235                     /* look at the symbol got offset. If none, then add one */
    1236                     if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
    1237                         reloc_type = R_X86_64_GLOB_DAT;
    1238                     else
    1239                         reloc_type = R_X86_64_JUMP_SLOT;
    1240                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
    1241                                   sym_index);
    1242                 }
    1243                 break;
    1244 #elif  defined(TCC_TARGET_IL)
    1245 #else
    1246 #error unsupported CPU
    1247 #endif
    1248             default:
    1249                 break;
    1250             }
    1251         }
    1252     }
    1253 }
    1254 
    1255 ST_FUNC Section *new_symtab(TCCState *s1,
    1256                            const char *symtab_name, int sh_type, int sh_flags,
    1257                            const char *strtab_name,
    1258                            const char *hash_name, int hash_sh_flags)
    1259 {
    1260     Section *symtab, *strtab, *hash;
    1261     int *ptr, nb_buckets;
    1262 
    1263     symtab = new_section(s1, symtab_name, sh_type, sh_flags);
    1264     symtab->sh_entsize = sizeof(ElfW(Sym));
    1265     strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
    1266     put_elf_str(strtab, "");
    1267     symtab->link = strtab;
    1268     put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
    1269    
    1270     nb_buckets = 1;
    1271 
    1272     hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
    1273     hash->sh_entsize = sizeof(int);
    1274     symtab->hash = hash;
    1275     hash->link = symtab;
    1276 
    1277     ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
    1278     ptr[0] = nb_buckets;
    1279     ptr[1] = 1;
    1280     memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
    1281     return symtab;
     1035            gotplt_entry = gotplt_entry_type(type);
     1036            sym_index = ELFW(R_SYM)(rel->r_info);
     1037            sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
     1038
     1039            if (gotplt_entry == NO_GOTPLT_ENTRY) {
     1040                continue;
     1041            }
     1042
     1043            /* Automatically create PLT/GOT [entry] if it is an undefined
     1044               reference (resolved at runtime), or the symbol is absolute,
     1045               probably created by tcc_add_symbol, and thus on 64-bit
     1046               targets might be too far from application code.  */
     1047            if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
     1048                if (sym->st_shndx == SHN_UNDEF) {
     1049                    ElfW(Sym) *esym;
     1050                    int dynindex;
     1051                    if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
     1052                        continue;
     1053                    /* Relocations for UNDEF symbols would normally need
     1054                       to be transferred into the executable or shared object.
     1055                       If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
     1056                       But TCC doesn't do that (at least for exes), so we
     1057                       need to resolve all such relocs locally.  And that
     1058                       means PLT slots for functions in DLLs and COPY relocs for
     1059                       data symbols.  COPY relocs were generated in
     1060                       bind_exe_dynsyms (and the symbol adjusted to be defined),
     1061                       and for functions we were generated a dynamic symbol
     1062                       of function type.  */
     1063                    if (s1->dynsym) {
     1064                        /* dynsym isn't set for -run :-/  */
     1065                        dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
     1066                        esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
     1067                        if (dynindex
     1068                            && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
     1069                                || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
     1070                                    && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
     1071                            goto jmp_slot;
     1072                    }
     1073                } else if (!(sym->st_shndx == SHN_ABS
     1074#ifndef TCC_TARGET_ARM
     1075                        && PTR_SIZE == 8
     1076#endif
     1077                        ))
     1078                    continue;
     1079            }
     1080
     1081#ifdef TCC_TARGET_X86_64
     1082            if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
     1083                (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
     1084                 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)) {
     1085                rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
     1086                continue;
     1087            }
     1088#endif
     1089            if (code_reloc(type)) {
     1090            jmp_slot:
     1091                reloc_type = R_JMP_SLOT;
     1092            } else
     1093                reloc_type = R_GLOB_DAT;
     1094
     1095            if (!s1->got)
     1096                build_got(s1);
     1097
     1098            if (gotplt_entry == BUILD_GOT_ONLY)
     1099                continue;
     1100
     1101            attr = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
     1102                                 sym_index);
     1103
     1104            if (reloc_type == R_JMP_SLOT)
     1105                rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
     1106        }
     1107    }
    12821108}
    12831109
     
    12911117}
    12921118
     1119#ifndef TCC_TARGET_PE
    12931120static void add_init_array_defines(TCCState *s1, const char *section_name)
    12941121{
     
    12971124    char sym_start[1024];
    12981125    char sym_end[1024];
    1299    
     1126
    13001127    snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
    13011128    snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
     
    13091136    }
    13101137
    1311     add_elf_sym(symtab_section,
     1138    set_elf_sym(symtab_section,
    13121139                0, 0,
    13131140                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    13141141                s->sh_num, sym_start);
    1315     add_elf_sym(symtab_section,
     1142    set_elf_sym(symtab_section,
    13161143                end_offset, 0,
    13171144                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    13181145                s->sh_num, sym_end);
    13191146}
    1320 
    1321 ST_FUNC void tcc_add_bcheck(TCCState *s1)
    1322 {
    1323 #ifdef CONFIG_TCC_BCHECK
    1324     unsigned long *ptr;
    1325     Section *init_section;
    1326     unsigned char *pinit;
    1327     int sym_index;
    1328 
    1329     if (0 == s1->do_bounds_check)
    1330         return;
    1331 
    1332     /* XXX: add an object file to do that */
    1333     ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
    1334     *ptr = 0;
    1335     add_elf_sym(symtab_section, 0, 0,
    1336                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    1337                 bounds_section->sh_num, "__bounds_start");
    1338 #ifdef TCC_TARGET_I386
    1339     if (s1->output_type != TCC_OUTPUT_MEMORY) {
    1340         /* add 'call __bound_init()' in .init section */
    1341         init_section = find_section(s1, ".init");
    1342         pinit = section_ptr_add(init_section, 5);
    1343         pinit[0] = 0xe8;
    1344         put32(pinit + 1, -4);
    1345         sym_index = find_elf_sym(symtab_section, "__bound_init");
    1346         put_elf_reloc(symtab_section, init_section,
    1347                       init_section->data_offset - 4, R_386_PC32, sym_index);
    1348     }
    1349 #endif
    1350 #endif
    1351 }
    1352 
    1353 static inline int tcc_add_support(TCCState *s1, const char *filename)
     1147#endif
     1148
     1149static int tcc_add_support(TCCState *s1, const char *filename)
    13541150{
    13551151    char buf[1024];
     
    13581154}
    13591155
     1156ST_FUNC void tcc_add_bcheck(TCCState *s1)
     1157{
     1158#ifdef CONFIG_TCC_BCHECK
     1159    addr_t *ptr;
     1160    int sym_index;
     1161
     1162    if (0 == s1->do_bounds_check)
     1163        return;
     1164    /* XXX: add an object file to do that */
     1165    ptr = section_ptr_add(bounds_section, sizeof(*ptr));
     1166    *ptr = 0;
     1167    set_elf_sym(symtab_section, 0, 0,
     1168                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
     1169                bounds_section->sh_num, "__bounds_start");
     1170    /* pull bcheck.o from libtcc1.a */
     1171    sym_index = set_elf_sym(symtab_section, 0, 0,
     1172                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
     1173                SHN_UNDEF, "__bound_init");
     1174    if (s1->output_type != TCC_OUTPUT_MEMORY) {
     1175        /* add 'call __bound_init()' in .init section */
     1176        Section *init_section = find_section(s1, ".init");
     1177        unsigned char *pinit = section_ptr_add(init_section, 5);
     1178        pinit[0] = 0xe8;
     1179        write32le(pinit + 1, -4);
     1180        put_elf_reloc(symtab_section, init_section,
     1181            init_section->data_offset - 4, R_386_PC32, sym_index);
     1182            /* R_386_PC32 = R_X86_64_PC32 = 2 */
     1183    }
     1184#endif
     1185}
     1186
    13601187/* add tcc runtime libraries */
    13611188ST_FUNC void tcc_add_runtime(TCCState *s1)
    13621189{
    13631190    tcc_add_bcheck(s1);
    1364 
     1191    tcc_add_pragma_libs(s1);
    13651192    /* add libc */
    13661193    if (!s1->nostdlib) {
    1367         tcc_add_library(s1, "c");
    1368 #ifdef CONFIG_USE_LIBGCC
    1369         tcc_add_file(s1, TCC_LIBGCC);
    1370 #elif !defined WITHOUT_LIBTCC
    1371         tcc_add_support(s1, "libtcc1.a");
    1372 #endif
     1194        tcc_add_library_err(s1, "c");
     1195#ifdef TCC_LIBGCC
     1196        if (!s1->static_link) {
     1197            if (TCC_LIBGCC[0] == '/')
     1198                tcc_add_file(s1, TCC_LIBGCC);
     1199            else
     1200                tcc_add_dll(s1, TCC_LIBGCC, 0);
     1201        }
     1202#endif
     1203        tcc_add_support(s1, TCC_LIBTCC1);
    13731204        /* add crt end if not memory output */
    13741205        if (s1->output_type != TCC_OUTPUT_MEMORY)
     
    13801211   sections are filled (for example after allocating common
    13811212   symbols)) */
    1382 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
     1213static void tcc_add_linker_symbols(TCCState *s1)
    13831214{
    13841215    char buf[1024];
     
    13861217    Section *s;
    13871218
    1388     add_elf_sym(symtab_section,
     1219    set_elf_sym(symtab_section,
    13891220                text_section->data_offset, 0,
    13901221                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    13911222                text_section->sh_num, "_etext");
    1392     add_elf_sym(symtab_section,
     1223    set_elf_sym(symtab_section,
    13931224                data_section->data_offset, 0,
    13941225                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    13951226                data_section->sh_num, "_edata");
    1396     add_elf_sym(symtab_section,
     1227    set_elf_sym(symtab_section,
    13971228                bss_section->data_offset, 0,
    13981229                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    13991230                bss_section->sh_num, "_end");
     1231#ifndef TCC_TARGET_PE
    14001232    /* horrible new standard ldscript defines */
    14011233    add_init_array_defines(s1, ".preinit_array");
    14021234    add_init_array_defines(s1, ".init_array");
    14031235    add_init_array_defines(s1, ".fini_array");
    1404    
     1236#endif
     1237
    14051238    /* add start and stop symbols for sections whose name can be
    14061239       expressed in C */
     
    14231256            }
    14241257            snprintf(buf, sizeof(buf), "__start_%s", s->name);
    1425             add_elf_sym(symtab_section,
     1258            set_elf_sym(symtab_section,
    14261259                        0, 0,
    14271260                        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
    14281261                        s->sh_num, buf);
    14291262            snprintf(buf, sizeof(buf), "__stop_%s", s->name);
    1430             add_elf_sym(symtab_section,
     1263            set_elf_sym(symtab_section,
    14311264                        s->data_offset, 0,
    14321265                        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
     
    14371270}
    14381271
     1272ST_FUNC void resolve_common_syms(TCCState *s1)
     1273{
     1274    ElfW(Sym) *sym;
     1275
     1276    /* Allocate common symbols in BSS.  */
     1277    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
     1278        if (sym->st_shndx == SHN_COMMON) {
     1279            /* symbol alignment is in st_value for SHN_COMMONs */
     1280            sym->st_value = section_add(bss_section, sym->st_size,
     1281                                        sym->st_value);
     1282            sym->st_shndx = bss_section->sh_num;
     1283        }
     1284    }
     1285
     1286    /* Now assign linker provided symbols their value.  */
     1287    tcc_add_linker_symbols(s1);
     1288}
     1289
    14391290static void tcc_output_binary(TCCState *s1, FILE *f,
    1440                               const int *section_order)
     1291                              const int *sec_order)
    14411292{
    14421293    Section *s;
     
    14451296    offset = 0;
    14461297    for(i=1;i<s1->nb_sections;i++) {
    1447         s = s1->sections[section_order[i]];
     1298        s = s1->sections[sec_order[i]];
    14481299        if (s->sh_type != SHT_NOBITS &&
    14491300            (s->sh_flags & SHF_ALLOC)) {
     
    14591310}
    14601311
    1461 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    1462 #define HAVE_PHDR       1
    1463 #define EXTRA_RELITEMS  14
    1464 
    1465 /* move the relocation value from .dynsym to .got */
    1466 void patch_dynsym_undef(TCCState *s1, Section *s)
    1467 {
    1468     uint32_t *gotd = (void *)s1->got->data;
    1469     ElfW(Sym) *sym, *sym_end;
    1470 
    1471     gotd += 3;  // dummy entries in .got
    1472     /* relocate symbols in .dynsym */
    1473     sym_end = (ElfW(Sym) *)(s->data + s->data_offset);
    1474     for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++) {
    1475         if (sym->st_shndx == SHN_UNDEF) {
    1476             *gotd++ = sym->st_value + 6; // XXX 6 is magic ?
    1477             sym->st_value = 0;
     1312ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
     1313{
     1314    int sym_index = ELFW(R_SYM) (rel->r_info);
     1315    ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
     1316    struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
     1317    unsigned offset = attr->got_offset;
     1318
     1319    if (0 == offset)
     1320        return;
     1321    section_reserve(s1->got, offset + PTR_SIZE);
     1322#ifdef TCC_TARGET_X86_64
     1323    write64le(s1->got->data + offset, sym->st_value);
     1324#else
     1325    write32le(s1->got->data + offset, sym->st_value);
     1326#endif
     1327}
     1328
     1329/* Perform relocation to GOT or PLT entries */
     1330ST_FUNC void fill_got(TCCState *s1)
     1331{
     1332    Section *s;
     1333    ElfW_Rel *rel;
     1334    int i;
     1335
     1336    for(i = 1; i < s1->nb_sections; i++) {
     1337        s = s1->sections[i];
     1338        if (s->sh_type != SHT_RELX)
     1339            continue;
     1340        /* no need to handle got relocations */
     1341        if (s->link != symtab_section)
     1342            continue;
     1343        for_each_elem(s, 0, rel, ElfW_Rel) {
     1344            switch (ELFW(R_TYPE) (rel->r_info)) {
     1345                case R_X86_64_GOT32:
     1346                case R_X86_64_GOTPCREL:
     1347                case R_X86_64_GOTPCRELX:
     1348                case R_X86_64_REX_GOTPCRELX:
     1349                case R_X86_64_PLT32:
     1350                    fill_got_entry(s1, rel);
     1351                    break;
     1352            }
     1353        }
     1354    }
     1355}
     1356
     1357/* See put_got_entry for a description.  This is the second stage
     1358   where GOT references to local defined symbols are rewritten.  */
     1359static void fill_local_got_entries(TCCState *s1)
     1360{
     1361    ElfW_Rel *rel;
     1362    for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
     1363        if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
     1364            int sym_index = ELFW(R_SYM) (rel->r_info);
     1365            ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
     1366            struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
     1367            unsigned offset = attr->got_offset;
     1368            if (offset != rel->r_offset - s1->got->sh_addr)
     1369              tcc_error_noabort("huh");
     1370            rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
     1371#if SHT_RELX == SHT_RELA
     1372            rel->r_addend = sym->st_value;
     1373#else
     1374            /* All our REL architectures also happen to be 32bit LE.  */
     1375            write32le(s1->got->data + offset, sym->st_value);
     1376#endif
    14781377        }
    14791378    }
    14801379}
    1481 #else
    1482 #define HAVE_PHDR       0
    1483 #define EXTRA_RELITEMS  9
    1484 
    1485 /* zero plt offsets of weak symbols in .dynsym */
    1486 void patch_dynsym_undef(TCCState *s1, Section *s)
    1487 {
    1488     ElfW(Sym) *sym, *sym_end;
    1489 
    1490     sym_end = (ElfW(Sym) *)(s->data + s->data_offset);
    1491     for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++)
    1492         if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
    1493             sym->st_value = 0;
    1494 }
    1495 #endif
    1496 
    1497 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
    1498 {
    1499         int sym_index = ELFW(R_SYM) (rel->r_info);
    1500         ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
    1501         unsigned long offset;
    1502 
    1503         if (sym_index >= s1->nb_sym_attrs)
    1504                 return;
    1505         offset = s1->sym_attrs[sym_index].got_offset;
    1506         section_reserve(s1->got, offset + PTR_SIZE);
    1507 #ifdef TCC_TARGET_X86_64
    1508         /* only works for x86-64 */
    1509         put32(s1->got->data + offset + 4, sym->st_value >> 32);
    1510 #endif
    1511         put32(s1->got->data + offset, sym->st_value & 0xffffffff);
    1512 }
    1513 
    1514 ST_FUNC void fill_got(TCCState *s1)
    1515 {
    1516         Section *s;
    1517         ElfW_Rel *rel, *rel_end;
    1518         int i;
    1519 
    1520         for(i = 1; i < s1->nb_sections; i++) {
    1521                 s = s1->sections[i];
    1522                 if (s->sh_type != SHT_RELX)
    1523                         continue;
    1524                 /* no need to handle got relocations */
    1525                 if (s->link != symtab_section)
    1526                         continue;
    1527                 rel_end = (ElfW_Rel *) (s->data + s->data_offset);
    1528                 for(rel = (ElfW_Rel *) s->data; rel < rel_end; rel++) {
    1529                         switch (ELFW(R_TYPE) (rel->r_info)) {
    1530                         case R_X86_64_GOT32:
    1531                         case R_X86_64_GOTPCREL:
    1532                         case R_X86_64_PLT32:
    1533                                 fill_got_entry(s1, rel);
    1534                                 break;
    1535                         }
    1536                 }
    1537         }
    1538 }
    1539 
    1540 
    1541 /* output an ELF file */
    1542 /* XXX: suppress unneeded sections */
    1543 static int elf_output_file(TCCState *s1, const char *filename)
    1544 {
    1545     ElfW(Ehdr) ehdr;
    1546     FILE *f;
    1547     int fd, mode, ret;
    1548     int *section_order;
    1549     int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k;
    1550     long long tmp;
    1551     addr_t addr;
    1552     Section *strsec, *s;
    1553     ElfW(Shdr) shdr, *sh;
    1554     ElfW(Phdr) *phdr, *ph;
    1555     Section *interp, *dynamic, *dynstr;
    1556     unsigned long saved_dynamic_data_offset;
    1557     ElfW(Sym) *sym;
    1558     int type, file_type;
    1559     addr_t rel_addr, rel_size;
    1560 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    1561     addr_t bss_addr, bss_size;
    1562 #endif
    1563 
    1564     file_type = s1->output_type;
    1565     s1->nb_errors = 0;
    1566 
    1567     if (file_type != TCC_OUTPUT_OBJ) {
    1568         tcc_add_runtime(s1);
    1569     }
    1570 
    1571     phdr = NULL;
    1572     section_order = NULL;
    1573     interp = NULL;
    1574     dynamic = NULL;
    1575     dynstr = NULL; /* avoid warning */
    1576     saved_dynamic_data_offset = 0; /* avoid warning */
    1577    
    1578     if (file_type != TCC_OUTPUT_OBJ) {
    1579         relocate_common_syms();
    1580 
    1581         tcc_add_linker_symbols(s1);
    1582 
    1583         if (!s1->static_link) {
    1584             const char *name;
    1585             int sym_index, index;
    1586             ElfW(Sym) *esym, *sym_end;
    1587 
    1588             if (file_type == TCC_OUTPUT_EXE) {
    1589                 char *ptr;
    1590                 /* allow override the dynamic loader */
    1591                 const char *elfint = getenv("LD_SO");
    1592                 if (elfint == NULL)
    1593                     elfint = CONFIG_TCC_ELFINTERP;
    1594                 /* add interpreter section only if executable */
    1595                 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
    1596                 interp->sh_addralign = 1;
    1597                 ptr = section_ptr_add(interp, 1+strlen(elfint));
    1598                 strcpy(ptr, elfint);
    1599             }
    1600 
    1601             /* add dynamic symbol table */
    1602             s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
    1603                                     ".dynstr",
    1604                                     ".hash", SHF_ALLOC);
    1605             dynstr = s1->dynsym->link;
    1606            
    1607             /* add dynamic section */
    1608             dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
    1609                                   SHF_ALLOC | SHF_WRITE);
    1610             dynamic->link = dynstr;
    1611             dynamic->sh_entsize = sizeof(ElfW(Dyn));
    1612        
    1613             /* add PLT */
    1614             s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
    1615                                   SHF_ALLOC | SHF_EXECINSTR);
    1616             s1->plt->sh_entsize = 4;
    1617 
    1618             build_got(s1);
    1619 
    1620             /* scan for undefined symbols and see if they are in the
    1621                dynamic symbols. If a symbol STT_FUNC or STT_GNU_IFUNC
    1622                is found, then we add it in the PLT. If a symbol
    1623                STT_OBJECT is found, we add it in the .bss section with
    1624                a suitable relocation */
    1625             sym_end = (ElfW(Sym) *)(symtab_section->data +
    1626                                     symtab_section->data_offset);
    1627             if (file_type == TCC_OUTPUT_EXE) {
    1628                 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
    1629                     sym < sym_end;
    1630                     sym++) {
    1631                     if (sym->st_shndx == SHN_UNDEF) {
    1632                         name = symtab_section->link->data + sym->st_name;
    1633                         sym_index = find_elf_sym(s1->dynsymtab_section, name);
    1634                         if (sym_index) {
    1635                             esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
    1636                             type = ELFW(ST_TYPE)(esym->st_info);
    1637                             if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
    1638                                 /* Indirect functions shall have STT_FUNC type
    1639                                  * in executable dynsym section. Indeed, a dlsym
    1640                                  * call following a lazy resolution would pick
    1641                                  * the symbol value from the executable dynsym
    1642                                  * entry which would contain the address of the
    1643                                  * function wanted by the caller of dlsym
    1644                                  * instead of the address of the function that
    1645                                  * would return that address */
    1646                                 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
    1647                                               ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
    1648                                               sym - (ElfW(Sym) *)symtab_section->data);
    1649                             } else if (type == STT_OBJECT) {
    1650                                 unsigned long offset;
    1651                                 ElfW(Sym) *dynsym, *dynsym_end;
    1652                                 offset = bss_section->data_offset;
    1653                                 /* XXX: which alignment ? */
    1654                                 offset = (offset + 16 - 1) & -16;
    1655                                 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
    1656                                                     esym->st_info, 0,
    1657                                                     bss_section->sh_num, name);
    1658                                 // Ensure R_COPY works for weak symbol aliases
    1659                                 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
    1660                                     dynsym_end = (ElfW(Sym) *)
    1661                                                  (s1->dynsymtab_section->data +
    1662                                                   s1->dynsymtab_section->data_offset);
    1663                                     for(dynsym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
    1664                                         dynsym < dynsym_end; dynsym++) {
    1665                                         if ((dynsym->st_value == esym->st_value)
    1666                                            && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
    1667                                             char *dynname;
    1668                                             dynname = s1->dynsymtab_section->link->data
    1669                                                       + dynsym->st_name;
    1670                                             put_elf_sym(s1->dynsym, offset,
    1671                                                         dynsym->st_size,
    1672                                                         dynsym->st_info, 0,
    1673                                                         bss_section->sh_num,
    1674                                                         dynname);
    1675                                             break;
    1676                                         }
    1677                                     }
    1678                                 }
    1679                                 put_elf_reloc(s1->dynsym, bss_section,
    1680                                               offset, R_COPY, index);
    1681                                 offset += esym->st_size;
    1682                                 bss_section->data_offset = offset;
    1683                             }
    1684                         } else {
    1685                                 /* STB_WEAK undefined symbols are accepted */
    1686                                 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
    1687                                    it */
    1688                             if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
    1689                                 !strcmp(name, "_fp_hw")) {
    1690                             } else {
    1691                                 tcc_error_noabort("undefined symbol '%s'", name);
    1692                             }
    1693                         }
    1694                     } else if (s1->rdynamic &&
    1695                                ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
    1696                         /* if -rdynamic option, then export all non
    1697                            local symbols */
    1698                         name = symtab_section->link->data + sym->st_name;
    1699                         put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
    1700                                     sym->st_info, 0,
    1701                                     sym->st_shndx, name);
    1702                     }
    1703                 }
    1704            
    1705                 if (s1->nb_errors)
    1706                     goto fail;
    1707 
    1708                 /* now look at unresolved dynamic symbols and export
    1709                    corresponding symbol */
    1710                 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
    1711                                         s1->dynsymtab_section->data_offset);
    1712                 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
    1713                     esym < sym_end;
    1714                     esym++) {
    1715                     if (esym->st_shndx == SHN_UNDEF) {
    1716                         name = s1->dynsymtab_section->link->data + esym->st_name;
    1717                         sym_index = find_elf_sym(symtab_section, name);
    1718                         if (sym_index) {
    1719                             /* XXX: avoid adding a symbol if already
    1720                                present because of -rdynamic ? */
    1721                             sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    1722                             put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
    1723                                         sym->st_info, 0,
    1724                                         sym->st_shndx, name);
    1725                         } else {
    1726                             if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
    1727                                 /* weak symbols can stay undefined */
    1728                             } else {
    1729                                 tcc_warning("undefined dynamic symbol '%s'", name);
     1380
     1381/* Bind symbols of executable: resolve undefined symbols from exported symbols
     1382   in shared libraries and export non local defined symbols to shared libraries
     1383   if -rdynamic switch was given on command line */
     1384static void bind_exe_dynsyms(TCCState *s1)
     1385{
     1386    const char *name;
     1387    int sym_index, index;
     1388    ElfW(Sym) *sym, *esym;
     1389    int type;
     1390
     1391    /* Resolve undefined symbols from dynamic symbols. When there is a match:
     1392       - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
     1393       - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
     1394    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
     1395        if (sym->st_shndx == SHN_UNDEF) {
     1396            name = (char *) symtab_section->link->data + sym->st_name;
     1397            sym_index = find_elf_sym(s1->dynsymtab_section, name);
     1398            if (sym_index) {
     1399                esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
     1400                type = ELFW(ST_TYPE)(esym->st_info);
     1401                if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
     1402                    /* Indirect functions shall have STT_FUNC type in executable
     1403                     * dynsym section. Indeed, a dlsym call following a lazy
     1404                     * resolution would pick the symbol value from the
     1405                     * executable dynsym entry which would contain the address
     1406                     * of the function wanted by the caller of dlsym instead of
     1407                     * the address of the function that would return that
     1408                     * address */
     1409                    int dynindex
     1410                      = put_elf_sym(s1->dynsym, 0, esym->st_size,
     1411                                    ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
     1412                                    name);
     1413                    int index = sym - (ElfW(Sym) *) symtab_section->data;
     1414                    get_sym_attr(s1, index, 1)->dyn_index = dynindex;
     1415                } else if (type == STT_OBJECT) {
     1416                    unsigned long offset;
     1417                    ElfW(Sym) *dynsym;
     1418                    offset = bss_section->data_offset;
     1419                    /* XXX: which alignment ? */
     1420                    offset = (offset + 16 - 1) & -16;
     1421                    set_elf_sym (s1->symtab, offset, esym->st_size,
     1422                                 esym->st_info, 0, bss_section->sh_num, name);
     1423                    index = put_elf_sym(s1->dynsym, offset, esym->st_size,
     1424                                        esym->st_info, 0, bss_section->sh_num,
     1425                                        name);
     1426
     1427                    /* Ensure R_COPY works for weak symbol aliases */
     1428                    if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
     1429                        for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
     1430                            if ((dynsym->st_value == esym->st_value)
     1431                                && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
     1432                                char *dynname = (char *) s1->dynsymtab_section->link->data
     1433                                                + dynsym->st_name;
     1434                                put_elf_sym(s1->dynsym, offset, dynsym->st_size,
     1435                                            dynsym->st_info, 0,
     1436                                            bss_section->sh_num, dynname);
     1437                                break;
    17301438                            }
    17311439                        }
    17321440                    }
     1441
     1442                    put_elf_reloc(s1->dynsym, bss_section,
     1443                                  offset, R_COPY, index);
     1444                    offset += esym->st_size;
     1445                    bss_section->data_offset = offset;
    17331446                }
    17341447            } else {
    1735                 int nb_syms;
    1736                 /* shared library case : we simply export all the global symbols */
    1737                 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
    1738                 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
    1739                 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
    1740                     sym < sym_end;
    1741                     sym++) {
    1742                     if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
    1743 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
    1744                         if ((ELFW(ST_TYPE)(sym->st_info) == STT_FUNC ||
    1745                             ELFW(ST_TYPE)(sym->st_info) == STT_GNU_IFUNC)
    1746                             && sym->st_shndx == SHN_UNDEF) {
    1747                             int visibility = ELFW(ST_BIND)(sym->st_info);
    1748                             put_got_entry(s1, R_JMP_SLOT, sym->st_size,
    1749                                           ELFW(ST_INFO)(visibility,STT_FUNC),
    1750                                           sym - (ElfW(Sym) *)symtab_section->data);
    1751                         }
    1752                         else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
    1753                             put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size,
    1754                                           sym->st_info,
    1755                                           sym - (ElfW(Sym) *)symtab_section->data);
    1756                         }
    1757                         else
    1758 #endif
    1759                         {
    1760                             name = symtab_section->link->data + sym->st_name;
    1761                             index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
    1762                                                 sym->st_info, 0,
    1763                                                 sym->st_shndx, name);
    1764                             s1->symtab_to_dynsym[sym -
    1765                                                  (ElfW(Sym) *)symtab_section->data] =
    1766                                 index;
    1767                         }
    1768                     }
     1448                /* STB_WEAK undefined symbols are accepted */
     1449                /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
     1450                if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
     1451                    !strcmp(name, "_fp_hw")) {
     1452                } else {
     1453                    tcc_error_noabort("undefined symbol '%s'", name);
    17691454                }
    17701455            }
    1771 
    1772             build_got_entries(s1);
    1773        
    1774             /* add a list of needed dlls */
    1775             for(i = 0; i < s1->nb_loaded_dlls; i++) {
    1776                 DLLReference *dllref = s1->loaded_dlls[i];
    1777                 if (dllref->level == 0)
    1778                     put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
    1779             }
    1780 
    1781             if (s1->rpath)
    1782                 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
    1783 
    1784             /* XXX: currently, since we do not handle PIC code, we
    1785                must relocate the readonly segments */
    1786             if (file_type == TCC_OUTPUT_DLL) {
    1787                 if (s1->soname)
    1788                     put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
    1789                 put_dt(dynamic, DT_TEXTREL, 0);
    1790             }
    1791 
    1792             if (s1->symbolic)
    1793                 put_dt(dynamic, DT_SYMBOLIC, 0);
    1794 
    1795             /* add necessary space for other entries */
    1796             saved_dynamic_data_offset = dynamic->data_offset;
    1797             dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
    1798         } else {
    1799             /* still need to build got entries in case of static link */
    1800             build_got_entries(s1);
    1801         }
    1802     }
    1803 
    1804     memset(&ehdr, 0, sizeof(ehdr));
    1805 
    1806     /* we add a section for symbols */
    1807     strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
    1808     put_elf_str(strsec, "");
    1809    
    1810     /* compute number of sections */
    1811     shnum = s1->nb_sections;
    1812 
    1813     /* this array is used to reorder sections in the output file */
    1814     section_order = tcc_malloc(sizeof(int) * shnum);
    1815     section_order[0] = 0;
    1816     sh_order_index = 1;
    1817    
    1818     /* compute number of program headers */
    1819     switch(file_type) {
    1820     default:
    1821     case TCC_OUTPUT_OBJ:
    1822         phnum = 0;
    1823         break;
    1824     case TCC_OUTPUT_EXE:
    1825         if (!s1->static_link)
    1826             phnum = 4 + HAVE_PHDR;
    1827         else
    1828             phnum = 2;
    1829         break;
    1830     case TCC_OUTPUT_DLL:
    1831         phnum = 3;
    1832         break;
    1833     }
    1834 
    1835     /* allocate strings for section names and decide if an unallocated
    1836        section should be output */
    1837     /* NOTE: the strsec section comes last, so its size is also
    1838        correct ! */
     1456        } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
     1457            /* if -rdynamic option, then export all non local symbols */
     1458            name = (char *) symtab_section->link->data + sym->st_name;
     1459            set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
     1460                        0, sym->st_shndx, name);
     1461        }
     1462    }
     1463}
     1464
     1465/* Bind symbols of libraries: export all non local symbols of executable that
     1466   are referenced by shared libraries. The reason is that the dynamic loader
     1467   search symbol first in executable and then in libraries. Therefore a
     1468   reference to a symbol already defined by a library can still be resolved by
     1469   a symbol in the executable. */
     1470static void bind_libs_dynsyms(TCCState *s1)
     1471{
     1472    const char *name;
     1473    int sym_index;
     1474    ElfW(Sym) *sym, *esym;
     1475
     1476    for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
     1477        name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
     1478        sym_index = find_elf_sym(symtab_section, name);
     1479        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
     1480        if (sym_index && sym->st_shndx != SHN_UNDEF
     1481            && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
     1482            set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
     1483                sym->st_info, 0, sym->st_shndx, name);
     1484        } else if (esym->st_shndx == SHN_UNDEF) {
     1485            /* weak symbols can stay undefined */
     1486            if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
     1487                tcc_warning("undefined dynamic symbol '%s'", name);
     1488        }
     1489    }
     1490}
     1491
     1492/* Export all non local symbols. This is used by shared libraries so that the
     1493   non local symbols they define can resolve a reference in another shared
     1494   library or in the executable. Correspondingly, it allows undefined local
     1495   symbols to be resolved by other shared libraries or by the executable. */
     1496static void export_global_syms(TCCState *s1)
     1497{
     1498    int dynindex, index;
     1499    const char *name;
     1500    ElfW(Sym) *sym;
     1501
     1502    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
     1503        if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
     1504            name = (char *) symtab_section->link->data + sym->st_name;
     1505            dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
     1506                                   sym->st_info, 0, sym->st_shndx, name);
     1507            index = sym - (ElfW(Sym) *) symtab_section->data;
     1508            get_sym_attr(s1, index, 1)->dyn_index = dynindex;
     1509        }
     1510    }
     1511}
     1512
     1513/* Allocate strings for section names and decide if an unallocated section
     1514   should be output.
     1515   NOTE: the strsec section comes last, so its size is also correct ! */
     1516static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
     1517{
     1518    int i;
     1519    Section *s;
     1520    int textrel = 0;
     1521
     1522    /* Allocate strings for section names */
    18391523    for(i = 1; i < s1->nb_sections; i++) {
    18401524        s = s1->sections[i];
    1841         s->sh_name = put_elf_str(strsec, s->name);
    1842 #if 0 //gr       
    1843         printf("section: f=%08x t=%08x i=%08x %s %s\n",
    1844                s->sh_flags,
    1845                s->sh_type,
    1846                s->sh_info,
    1847                s->name,
    1848                s->reloc ? s->reloc->name : "n"
    1849                );
    1850 #endif
    18511525        /* when generating a DLL, we include relocations but we may
    18521526           patch them */
    1853         if (file_type == TCC_OUTPUT_DLL &&
    1854             s->sh_type == SHT_RELX &&
    1855             !(s->sh_flags & SHF_ALLOC)) {
    1856             /* //gr: avoid bogus relocs for empty (debug) sections */
    1857             if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
    1858                 prepare_dynamic_rel(s1, s);
    1859             else if (s1->do_debug)
    1860                 s->sh_size = s->data_offset;
     1527        if (file_type == TCC_OUTPUT_DLL &&
     1528            s->sh_type == SHT_RELX &&
     1529            !(s->sh_flags & SHF_ALLOC) &&
     1530            (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
     1531            prepare_dynamic_rel(s1, s)) {
     1532                if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)
     1533                    textrel = 1;
    18611534        } else if (s1->do_debug ||
    1862             file_type == TCC_OUTPUT_OBJ || 
     1535            file_type == TCC_OUTPUT_OBJ ||
    18631536            (s->sh_flags & SHF_ALLOC) ||
    1864             i == (s1->nb_sections - 1)) {
     1537            i == (s1->nb_sections - 1)) {
    18651538            /* we output all sections if debug or object file */
    18661539            s->sh_size = s->data_offset;
    18671540        }
    1868     }
    1869 
    1870     /* allocate program segment headers */
    1871     phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
    1872        
    1873     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
     1541        if (s->sh_size || (s->sh_flags & SHF_ALLOC))
     1542            s->sh_name = put_elf_str(strsec, s->name);
     1543    }
     1544    strsec->sh_size = strsec->data_offset;
     1545    return textrel;
     1546}
     1547
     1548/* Info to be copied in dynamic section */
     1549struct dyn_inf {
     1550    Section *dynamic;
     1551    Section *dynstr;
     1552    unsigned long data_offset;
     1553    addr_t rel_addr;
     1554    addr_t rel_size;
     1555#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     1556    addr_t bss_addr;
     1557    addr_t bss_size;
     1558#endif
     1559};
     1560
     1561/* Assign sections to segments and decide how are sections laid out when loaded
     1562   in memory. This function also fills corresponding program headers. */
     1563static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
     1564                           Section *interp, Section* strsec,
     1565                           struct dyn_inf *dyninf, int *sec_order)
     1566{
     1567    int i, j, k, file_type, sh_order_index, file_offset;
     1568    unsigned long s_align;
     1569    long long tmp;
     1570    addr_t addr;
     1571    ElfW(Phdr) *ph;
     1572    Section *s;
     1573
     1574    file_type = s1->output_type;
     1575    sh_order_index = 1;
     1576    file_offset = 0;
     1577    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
    18741578        file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
    1875     } else {
    1876         file_offset = 0;
    1877     }
     1579    s_align = ELF_PAGE_SIZE;
     1580    if (s1->section_align)
     1581        s_align = s1->section_align;
     1582
    18781583    if (phnum > 0) {
    1879         /* compute section to program header mapping */
    1880         if (s1->has_text_addr) {
     1584        if (s1->has_text_addr) {
    18811585            int a_offset, p_offset;
    18821586            addr = s1->text_addr;
    18831587            /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
    18841588               ELF_PAGE_SIZE */
    1885             a_offset = (int) (addr & (s1->section_align - 1));
    1886             p_offset = file_offset & (s1->section_align - 1);
    1887             if (a_offset < p_offset) 
    1888                 a_offset += s1->section_align;
     1589            a_offset = (int) (addr & (s_align - 1));
     1590            p_offset = file_offset & (s_align - 1);
     1591            if (a_offset < p_offset)
     1592                a_offset += s_align;
    18891593            file_offset += (a_offset - p_offset);
    18901594        } else {
     
    18941598                addr = ELF_START_ADDR;
    18951599            /* compute address after headers */
    1896             addr += (file_offset & (s1->section_align - 1));
    1897         }
    1898        
     1600            addr += (file_offset & (s_align - 1));
     1601        }
     1602
     1603        ph = &phdr[0];
     1604        /* Leave one program headers for the program interpreter and one for
     1605           the program header table itself if needed. These are done later as
     1606           they require section layout to be done first. */
     1607        if (interp)
     1608            ph += 2;
     1609
    18991610        /* dynamic relocation table information, for .dynamic section */
    1900         rel_size = 0;
    1901         rel_addr = 0;
    1902 
     1611        dyninf->rel_addr = dyninf->rel_size = 0;
    19031612#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    1904         bss_addr = bss_size = 0;
    1905 #endif
    1906         /* leave one program header for the program interpreter */
    1907         ph = &phdr[0];
    1908         if (interp)
    1909             ph += 1 + HAVE_PHDR;
     1613        dyninf->bss_addr = dyninf->bss_size = 0;
     1614#endif
    19101615
    19111616        for(j = 0; j < 2; j++) {
     
    19151620            else
    19161621                ph->p_flags = PF_R | PF_W;
    1917             ph->p_align = s1->section_align;
    1918            
    1919             /* we do the following ordering: interp, symbol tables,
    1920                relocations, progbits, nobits */
     1622            ph->p_align = s_align;
     1623
     1624            /* Decide the layout of sections loaded in memory. This must
     1625               be done before program headers are filled since they contain
     1626               info about the layout. We do the following ordering: interp,
     1627               symbol tables, relocations, progbits, nobits */
    19211628            /* XXX: do faster and simpler sorting */
    19221629            for(k = 0; k < 5; k++) {
     
    19251632                    /* compute if section should be included */
    19261633                    if (j == 0) {
    1927                         if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
     1634                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
    19281635                            SHF_ALLOC)
    19291636                            continue;
    19301637                    } else {
    1931                         if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
     1638                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
    19321639                            (SHF_ALLOC | SHF_WRITE))
    19331640                            continue;
     
    19511658                            continue;
    19521659                    }
    1953                     section_order[sh_order_index++] = i;
     1660                    sec_order[sh_order_index++] = i;
    19541661
    19551662                    /* section matches: we align it and add its size */
    19561663                    tmp = addr;
    1957                     addr = (addr + s->sh_addralign - 1) & 
     1664                    addr = (addr + s->sh_addralign - 1) &
    19581665                        ~(s->sh_addralign - 1);
    19591666                    file_offset += (int) ( addr - tmp );
    19601667                    s->sh_offset = file_offset;
    19611668                    s->sh_addr = addr;
    1962                    
     1669
    19631670                    /* update program header infos */
    19641671                    if (ph->p_offset == 0) {
     
    19701677                    if (s->sh_type == SHT_RELX) {
    19711678#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    1972                         if (!strcmp(strsec->data + s->sh_name, ".rel.got")) { // rel_size == 0) {
    1973                             rel_addr = addr;
    1974                             rel_size += s->sh_size;     // XXX only first rel.
    1975                         }
    1976                         if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) { // rel_size == 0) {
    1977                             bss_addr = addr;
    1978                             bss_size = s->sh_size;      // XXX only first rel.
    1979                         }
     1679                        if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
     1680                            dyninf->rel_addr = addr;
     1681                            dyninf->rel_size += s->sh_size; /* XXX only first rel. */
     1682                        }
     1683                        if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
     1684                            dyninf->bss_addr = addr;
     1685                            dyninf->bss_size = s->sh_size; /* XXX only first rel. */
     1686                        }
    19801687#else
    1981                         if (rel_size == 0)
    1982                             rel_addr = addr;
    1983                         rel_size += s->sh_size;
     1688                        if (dyninf->rel_size == 0)
     1689                            dyninf->rel_addr = addr;
     1690                        dyninf->rel_size += s->sh_size;
    19841691#endif
    19851692                    }
     
    19891696                }
    19901697            }
     1698            if (j == 0) {
     1699                /* Make the first PT_LOAD segment include the program
     1700                   headers itself (and the ELF header as well), it'll
     1701                   come out with same memory use but will make various
     1702                   tools like binutils strip work better.  */
     1703                ph->p_offset &= ~(ph->p_align - 1);
     1704                ph->p_vaddr &= ~(ph->p_align - 1);
     1705                ph->p_paddr &= ~(ph->p_align - 1);
     1706            }
    19911707            ph->p_filesz = file_offset - ph->p_offset;
    19921708            ph->p_memsz = addr - ph->p_vaddr;
     
    19961712                    /* if in the middle of a page, we duplicate the page in
    19971713                       memory so that one copy is RX and the other is RW */
    1998                     if ((addr & (s1->section_align - 1)) != 0)
    1999                         addr += s1->section_align;
     1714                    if ((addr & (s_align - 1)) != 0)
     1715                        addr += s_align;
    20001716                } else {
    2001                     addr = (addr + s1->section_align - 1) & ~(s1->section_align - 1);
    2002                     file_offset = (file_offset + s1->section_align - 1) &
    2003                         ~(s1->section_align - 1);
     1717                    addr = (addr + s_align - 1) & ~(s_align - 1);
     1718                    file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
    20041719                }
    20051720            }
    20061721        }
    2007 
    2008         /* if interpreter, then add corresponing program header */
    2009         if (interp) {
    2010             ph = &phdr[0];
    2011 
    2012 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    2013             {
    2014                 int len = phnum * sizeof(ElfW(Phdr));
    2015 
    2016                 ph->p_type = PT_PHDR;
    2017                 ph->p_offset = sizeof(ElfW(Ehdr));
    2018                 ph->p_vaddr = interp->sh_addr - len;
    2019                 ph->p_paddr = ph->p_vaddr;
    2020                 ph->p_filesz = ph->p_memsz = len;
    2021                 ph->p_flags = PF_R | PF_X;
    2022                 ph->p_align = 4; // interp->sh_addralign;
    2023                 ph++;
    2024             }
    2025 #endif
    2026 
    2027             ph->p_type = PT_INTERP;
    2028             ph->p_offset = interp->sh_offset;
    2029             ph->p_vaddr = interp->sh_addr;
    2030             ph->p_paddr = ph->p_vaddr;
    2031             ph->p_filesz = interp->sh_size;
    2032             ph->p_memsz = interp->sh_size;
    2033             ph->p_flags = PF_R;
    2034             ph->p_align = interp->sh_addralign;
    2035         }
    2036        
    2037         /* if dynamic section, then add corresponing program header */
    2038         if (dynamic) {
    2039             ElfW(Sym) *sym_end;
    2040 
    2041             ph = &phdr[phnum - 1];
    2042            
    2043             ph->p_type = PT_DYNAMIC;
    2044             ph->p_offset = dynamic->sh_offset;
    2045             ph->p_vaddr = dynamic->sh_addr;
    2046             ph->p_paddr = ph->p_vaddr;
    2047             ph->p_filesz = dynamic->sh_size;
    2048             ph->p_memsz = dynamic->sh_size;
    2049             ph->p_flags = PF_R | PF_W;
    2050             ph->p_align = dynamic->sh_addralign;
    2051 
    2052             /* put GOT dynamic section address */
    2053             put32(s1->got->data, dynamic->sh_addr);
    2054 
    2055             /* relocate the PLT */
    2056             if (file_type == TCC_OUTPUT_EXE
    2057 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
    2058                 || file_type == TCC_OUTPUT_DLL
    2059 #endif
    2060                 ) {
    2061                 uint8_t *p, *p_end;
    2062 
    2063                 p = s1->plt->data;
    2064                 p_end = p + s1->plt->data_offset;
    2065                 if (p < p_end) {
    2066 #if defined(TCC_TARGET_I386)
    2067                     put32(p + 2, get32(p + 2) + s1->got->sh_addr);
    2068                     put32(p + 8, get32(p + 8) + s1->got->sh_addr);
    2069                     p += 16;
    2070                     while (p < p_end) {
    2071                         put32(p + 2, get32(p + 2) + s1->got->sh_addr);
    2072                         p += 16;
    2073                     }
    2074 #elif defined(TCC_TARGET_X86_64)
    2075                     int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
    2076                     put32(p + 2, get32(p + 2) + x);
    2077                     put32(p + 8, get32(p + 8) + x - 6);
    2078                     p += 16;
    2079                     while (p < p_end) {
    2080                         put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
    2081                         p += 16;
    2082                     }
    2083 #elif defined(TCC_TARGET_ARM)
    2084                     int x;
    2085                     x=s1->got->sh_addr - s1->plt->sh_addr - 12;
    2086                     p += 16;
    2087                     while (p < p_end) {
    2088                         if (get32(p) == 0x46c04778) /* PLT Thumb stub present */
    2089                             p += 4;
    2090                         put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
    2091                         p += 16;
    2092                     }
    2093 #elif defined(TCC_TARGET_C67)
    2094                     /* XXX: TODO */
    2095 #elif  defined(TCC_TARGET_IL)
    2096 #else
    2097 #error unsupported CPU
    2098 #endif
    2099                 }
    2100             }
    2101 
    2102             /* relocate symbols in .dynsym */
    2103             sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
    2104             for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
    2105                 sym < sym_end;
    2106                 sym++) {
    2107                 if (sym->st_shndx == SHN_UNDEF) {
    2108                     /* relocate to the PLT if the symbol corresponds
    2109                        to a PLT entry */
    2110                     if (sym->st_value)
    2111                         sym->st_value += s1->plt->sh_addr;
    2112                 } else if (sym->st_shndx < SHN_LORESERVE) {
    2113                     /* do symbol relocation */
    2114                     sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
    2115                 }
    2116             }
    2117 
    2118             /* put dynamic section entries */
    2119             dynamic->data_offset = saved_dynamic_data_offset;
    2120             put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
    2121             put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
    2122             put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
    2123             put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
    2124             put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
    2125 #ifdef TCC_TARGET_X86_64
    2126             put_dt(dynamic, DT_RELA, rel_addr);
    2127             put_dt(dynamic, DT_RELASZ, rel_size);
    2128             put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
    2129 #else
    2130 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    2131             put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
    2132             put_dt(dynamic, DT_PLTRELSZ, rel_size);
    2133             put_dt(dynamic, DT_JMPREL, rel_addr);
    2134             put_dt(dynamic, DT_PLTREL, DT_REL);
    2135             put_dt(dynamic, DT_REL, bss_addr);
    2136             put_dt(dynamic, DT_RELSZ, bss_size);
    2137 #else
    2138             put_dt(dynamic, DT_REL, rel_addr);
    2139             put_dt(dynamic, DT_RELSZ, rel_size);
    2140             put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
    2141 #endif
    2142 #endif
    2143             if (s1->do_debug)
    2144                 put_dt(dynamic, DT_DEBUG, 0);
    2145             put_dt(dynamic, DT_NULL, 0);
    2146         }
    2147 
    2148         ehdr.e_phentsize = sizeof(ElfW(Phdr));
    2149         ehdr.e_phnum = phnum;
    2150         ehdr.e_phoff = sizeof(ElfW(Ehdr));
    21511722    }
    21521723
     
    21561727        if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
    21571728            continue;
    2158         section_order[sh_order_index++] = i;
    2159        
    2160         file_offset = (file_offset + s->sh_addralign - 1) & 
     1729        sec_order[sh_order_index++] = i;
     1730
     1731        file_offset = (file_offset + s->sh_addralign - 1) &
    21611732            ~(s->sh_addralign - 1);
    21621733        s->sh_offset = file_offset;
     
    21641735            file_offset += s->sh_size;
    21651736    }
    2166    
    2167     /* if building executable or DLL, then relocate each section
    2168        except the GOT which is already relocated */
    2169     if (file_type != TCC_OUTPUT_OBJ) {
    2170         relocate_syms(s1, 0);
    2171 
    2172         if (s1->nb_errors != 0) {
    2173         fail:
    2174             ret = -1;
    2175             goto the_end;
    2176         }
    2177 
    2178         /* relocate sections */
    2179         /* XXX: ignore sections with allocated relocations ? */
    2180         for(i = 1; i < s1->nb_sections; i++) {
    2181             s = s1->sections[i];
    2182             if (s->reloc && s != s1->got)
    2183                 relocate_section(s1, s);
    2184         }
    2185 
    2186         /* relocate relocation entries if the relocation tables are
    2187            allocated in the executable */
    2188         for(i = 1; i < s1->nb_sections; i++) {
    2189             s = s1->sections[i];
    2190             if ((s->sh_flags & SHF_ALLOC) &&
    2191                 s->sh_type == SHT_RELX) {
    2192                 relocate_rel(s1, s);
    2193             }
    2194         }
    2195 
    2196         /* get entry point address */
    2197         if (file_type == TCC_OUTPUT_EXE)
    2198             ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
    2199         else
    2200             ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
    2201     }
    2202     if (file_type == TCC_OUTPUT_EXE && s1->static_link)
    2203         fill_got(s1);
    2204 
    2205     /* write elf file */
     1737
     1738    return file_offset;
     1739}
     1740
     1741static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
     1742                                 Section *dynamic)
     1743{
     1744    ElfW(Phdr) *ph;
     1745
     1746    /* if interpreter, then add corresponding program header */
     1747    if (interp) {
     1748        ph = &phdr[0];
     1749
     1750        ph->p_type = PT_PHDR;
     1751        ph->p_offset = sizeof(ElfW(Ehdr));
     1752        ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
     1753        ph->p_vaddr = interp->sh_addr - ph->p_filesz;
     1754        ph->p_paddr = ph->p_vaddr;
     1755        ph->p_flags = PF_R | PF_X;
     1756        ph->p_align = 4; /* interp->sh_addralign; */
     1757        ph++;
     1758
     1759        ph->p_type = PT_INTERP;
     1760        ph->p_offset = interp->sh_offset;
     1761        ph->p_vaddr = interp->sh_addr;
     1762        ph->p_paddr = ph->p_vaddr;
     1763        ph->p_filesz = interp->sh_size;
     1764        ph->p_memsz = interp->sh_size;
     1765        ph->p_flags = PF_R;
     1766        ph->p_align = interp->sh_addralign;
     1767    }
     1768
     1769    /* if dynamic section, then add corresponding program header */
     1770    if (dynamic) {
     1771        ph = &phdr[phnum - 1];
     1772
     1773        ph->p_type = PT_DYNAMIC;
     1774        ph->p_offset = dynamic->sh_offset;
     1775        ph->p_vaddr = dynamic->sh_addr;
     1776        ph->p_paddr = ph->p_vaddr;
     1777        ph->p_filesz = dynamic->sh_size;
     1778        ph->p_memsz = dynamic->sh_size;
     1779        ph->p_flags = PF_R | PF_W;
     1780        ph->p_align = dynamic->sh_addralign;
     1781    }
     1782}
     1783
     1784/* Fill the dynamic section with tags describing the address and size of
     1785   sections */
     1786static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
     1787{
     1788    Section *dynamic = dyninf->dynamic;
     1789
     1790    /* put dynamic section entries */
     1791    put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
     1792    put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
     1793    put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
     1794    put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
     1795    put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
     1796#if PTR_SIZE == 8
     1797    put_dt(dynamic, DT_RELA, dyninf->rel_addr);
     1798    put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
     1799    put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
     1800#else
     1801#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     1802    put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
     1803    put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
     1804    put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
     1805    put_dt(dynamic, DT_PLTREL, DT_REL);
     1806    put_dt(dynamic, DT_REL, dyninf->bss_addr);
     1807    put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
     1808#else
     1809    put_dt(dynamic, DT_REL, dyninf->rel_addr);
     1810    put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
     1811    put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
     1812#endif
     1813#endif
     1814    if (s1->do_debug)
     1815        put_dt(dynamic, DT_DEBUG, 0);
     1816    put_dt(dynamic, DT_NULL, 0);
     1817}
     1818
     1819/* Relocate remaining sections and symbols (that is those not related to
     1820   dynamic linking) */
     1821static int final_sections_reloc(TCCState *s1)
     1822{
     1823    int i;
     1824    Section *s;
     1825
     1826    relocate_syms(s1, s1->symtab, 0);
     1827
     1828    if (s1->nb_errors != 0)
     1829        return -1;
     1830
     1831    /* relocate sections */
     1832    /* XXX: ignore sections with allocated relocations ? */
     1833    for(i = 1; i < s1->nb_sections; i++) {
     1834        s = s1->sections[i];
     1835#if defined(TCC_TARGET_I386) || defined(TCC_MUSL)
     1836        if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
     1837        /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
     1838        checking is removed */
     1839#else
     1840        if (s->reloc && s != s1->got)
     1841        /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
     1842#endif
     1843            relocate_section(s1, s);
     1844    }
     1845
     1846    /* relocate relocation entries if the relocation tables are
     1847       allocated in the executable */
     1848    for(i = 1; i < s1->nb_sections; i++) {
     1849        s = s1->sections[i];
     1850        if ((s->sh_flags & SHF_ALLOC) &&
     1851            s->sh_type == SHT_RELX) {
     1852            relocate_rel(s1, s);
     1853        }
     1854    }
     1855    return 0;
     1856}
     1857
     1858/* Create an ELF file on disk.
     1859   This function handle ELF specific layout requirements */
     1860static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
     1861                           int file_offset, int *sec_order)
     1862{
     1863    int i, shnum, offset, size, file_type;
     1864    Section *s;
     1865    ElfW(Ehdr) ehdr;
     1866    ElfW(Shdr) shdr, *sh;
     1867
     1868    file_type = s1->output_type;
     1869    shnum = s1->nb_sections;
     1870
     1871    memset(&ehdr, 0, sizeof(ehdr));
     1872
     1873    if (phnum > 0) {
     1874        ehdr.e_phentsize = sizeof(ElfW(Phdr));
     1875        ehdr.e_phnum = phnum;
     1876        ehdr.e_phoff = sizeof(ElfW(Ehdr));
     1877    }
     1878
     1879    /* align to 4 */
     1880    file_offset = (file_offset + 3) & -4;
     1881
     1882    /* fill header */
     1883    ehdr.e_ident[0] = ELFMAG0;
     1884    ehdr.e_ident[1] = ELFMAG1;
     1885    ehdr.e_ident[2] = ELFMAG2;
     1886    ehdr.e_ident[3] = ELFMAG3;
     1887    ehdr.e_ident[4] = ELFCLASSW;
     1888    ehdr.e_ident[5] = ELFDATA2LSB;
     1889    ehdr.e_ident[6] = EV_CURRENT;
     1890#if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
     1891    /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
     1892    ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
     1893#endif
     1894#ifdef TCC_TARGET_ARM
     1895#ifdef TCC_ARM_EABI
     1896    ehdr.e_ident[EI_OSABI] = 0;
     1897    ehdr.e_flags = EF_ARM_EABI_VER4;
     1898    if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
     1899        ehdr.e_flags |= EF_ARM_HASENTRY;
     1900    if (s1->float_abi == ARM_HARD_FLOAT)
     1901        ehdr.e_flags |= EF_ARM_VFP_FLOAT;
     1902    else
     1903        ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
     1904#else
     1905    ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
     1906#endif
     1907#endif
     1908    switch(file_type) {
     1909    default:
     1910    case TCC_OUTPUT_EXE:
     1911        ehdr.e_type = ET_EXEC;
     1912        ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
     1913        break;
     1914    case TCC_OUTPUT_DLL:
     1915        ehdr.e_type = ET_DYN;
     1916        ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
     1917        break;
     1918    case TCC_OUTPUT_OBJ:
     1919        ehdr.e_type = ET_REL;
     1920        break;
     1921    }
     1922    ehdr.e_machine = EM_TCC_TARGET;
     1923    ehdr.e_version = EV_CURRENT;
     1924    ehdr.e_shoff = file_offset;
     1925    ehdr.e_ehsize = sizeof(ElfW(Ehdr));
     1926    ehdr.e_shentsize = sizeof(ElfW(Shdr));
     1927    ehdr.e_shnum = shnum;
     1928    ehdr.e_shstrndx = shnum - 1;
     1929
     1930    fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
     1931    fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
     1932    offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
     1933
     1934    sort_syms(s1, symtab_section);
     1935    for(i = 1; i < s1->nb_sections; i++) {
     1936        s = s1->sections[sec_order[i]];
     1937        if (s->sh_type != SHT_NOBITS) {
     1938            while (offset < s->sh_offset) {
     1939                fputc(0, f);
     1940                offset++;
     1941            }
     1942            size = s->sh_size;
     1943            if (size)
     1944                fwrite(s->data, 1, size, f);
     1945            offset += size;
     1946        }
     1947    }
     1948
     1949    /* output section headers */
     1950    while (offset < ehdr.e_shoff) {
     1951        fputc(0, f);
     1952        offset++;
     1953    }
     1954
     1955    for(i = 0; i < s1->nb_sections; i++) {
     1956        sh = &shdr;
     1957        memset(sh, 0, sizeof(ElfW(Shdr)));
     1958        s = s1->sections[i];
     1959        if (s) {
     1960            sh->sh_name = s->sh_name;
     1961            sh->sh_type = s->sh_type;
     1962            sh->sh_flags = s->sh_flags;
     1963            sh->sh_entsize = s->sh_entsize;
     1964            sh->sh_info = s->sh_info;
     1965            if (s->link)
     1966                sh->sh_link = s->link->sh_num;
     1967            sh->sh_addralign = s->sh_addralign;
     1968            sh->sh_addr = s->sh_addr;
     1969            sh->sh_offset = s->sh_offset;
     1970            sh->sh_size = s->sh_size;
     1971        }
     1972        fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
     1973    }
     1974}
     1975
     1976/* Write an elf, coff or "binary" file */
     1977static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
     1978                              ElfW(Phdr) *phdr, int file_offset, int *sec_order)
     1979{
     1980    int fd, mode, file_type;
     1981    FILE *f;
     1982
     1983    file_type = s1->output_type;
    22061984    if (file_type == TCC_OUTPUT_OBJ)
    22071985        mode = 0666;
     
    22091987        mode = 0777;
    22101988    unlink(filename);
    2211     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); 
     1989    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
    22121990    if (fd < 0) {
    22131991        tcc_error_noabort("could not write '%s'", filename);
    2214         goto fail;
     1992        return -1;
    22151993    }
    22161994    f = fdopen(fd, "wb");
     
    22191997
    22201998#ifdef TCC_TARGET_COFF
    2221     if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
     1999    if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
    22222000        tcc_output_coff(s1, f);
    2223     } else
    2224 #endif
    2225     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
    2226         sort_syms(s1, symtab_section);
    2227        
    2228         /* align to 4 */
    2229         file_offset = (file_offset + 3) & -4;
    2230    
    2231         /* fill header */
    2232         ehdr.e_ident[0] = ELFMAG0;
    2233         ehdr.e_ident[1] = ELFMAG1;
    2234         ehdr.e_ident[2] = ELFMAG2;
    2235         ehdr.e_ident[3] = ELFMAG3;
    2236         ehdr.e_ident[4] = ELFCLASSW;
    2237         ehdr.e_ident[5] = ELFDATA2LSB;
    2238         ehdr.e_ident[6] = EV_CURRENT;
    2239 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    2240         ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
    2241 #endif
    2242 #ifdef TCC_TARGET_ARM
    2243 #ifdef TCC_ARM_EABI
    2244         ehdr.e_ident[EI_OSABI] = 0;
    2245         ehdr.e_flags = 4 << 24;
    2246 #else
    2247         ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
    2248 #endif
    2249 #endif
    2250         switch(file_type) {
    2251         default:
    2252         case TCC_OUTPUT_EXE:
    2253             ehdr.e_type = ET_EXEC;
    2254             break;
    2255         case TCC_OUTPUT_DLL:
    2256             ehdr.e_type = ET_DYN;
    2257             break;
    2258         case TCC_OUTPUT_OBJ:
    2259             ehdr.e_type = ET_REL;
    2260             break;
    2261         }
    2262         ehdr.e_machine = EM_TCC_TARGET;
    2263         ehdr.e_version = EV_CURRENT;
    2264         ehdr.e_shoff = file_offset;
    2265         ehdr.e_ehsize = sizeof(ElfW(Ehdr));
    2266         ehdr.e_shentsize = sizeof(ElfW(Shdr));
    2267         ehdr.e_shnum = shnum;
    2268         ehdr.e_shstrndx = shnum - 1;
    2269        
    2270         fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
    2271         fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
    2272         offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
    2273 
    2274         for(i=1;i<s1->nb_sections;i++) {
    2275             s = s1->sections[section_order[i]];
    2276             if (s->sh_type != SHT_NOBITS) {
    2277                 if (s->sh_type == SHT_DYNSYM)
    2278                     patch_dynsym_undef(s1, s);
    2279                 while (offset < s->sh_offset) {
    2280                     fputc(0, f);
    2281                     offset++;
     2001    else
     2002#endif
     2003    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
     2004        tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
     2005    else
     2006        tcc_output_binary(s1, f, sec_order);
     2007    fclose(f);
     2008
     2009    return 0;
     2010}
     2011
     2012/* Sort section headers by assigned sh_addr, remove sections
     2013   that we aren't going to output.  */
     2014static void tidy_section_headers(TCCState *s1, int *sec_order)
     2015{
     2016    int i, nnew, l, *backmap;
     2017    Section **snew, *s;
     2018    ElfW(Sym) *sym;
     2019
     2020    snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
     2021    backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
     2022    for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
     2023        s = s1->sections[sec_order[i]];
     2024        if (!i || s->sh_name) {
     2025            backmap[sec_order[i]] = nnew;
     2026            snew[nnew] = s;
     2027            ++nnew;
     2028        } else {
     2029            backmap[sec_order[i]] = 0;
     2030            snew[--l] = s;
     2031        }
     2032    }
     2033    for (i = 0; i < nnew; i++) {
     2034        s = snew[i];
     2035        if (s) {
     2036            s->sh_num = i;
     2037            if (s->sh_type == SHT_RELX)
     2038                s->sh_info = backmap[s->sh_info];
     2039        }
     2040    }
     2041
     2042    for_each_elem(symtab_section, 1, sym, ElfW(Sym))
     2043        if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
     2044            sym->st_shndx = backmap[sym->st_shndx];
     2045    if( !s1->static_link ) {
     2046        for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
     2047            if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
     2048                sym->st_shndx = backmap[sym->st_shndx];
     2049    }
     2050    for (i = 0; i < s1->nb_sections; i++)
     2051        sec_order[i] = i;
     2052    tcc_free(s1->sections);
     2053    s1->sections = snew;
     2054    s1->nb_sections = nnew;
     2055    tcc_free(backmap);
     2056}
     2057
     2058/* Output an elf, coff or binary file */
     2059/* XXX: suppress unneeded sections */
     2060static int elf_output_file(TCCState *s1, const char *filename)
     2061{
     2062    int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
     2063    struct dyn_inf dyninf = {0};
     2064    ElfW(Phdr) *phdr;
     2065    ElfW(Sym) *sym;
     2066    Section *strsec, *interp, *dynamic, *dynstr;
     2067    int textrel;
     2068
     2069    file_type = s1->output_type;
     2070    s1->nb_errors = 0;
     2071    ret = -1;
     2072    phdr = NULL;
     2073    sec_order = NULL;
     2074    interp = dynamic = dynstr = NULL; /* avoid warning */
     2075    textrel = 0;
     2076
     2077    if (file_type != TCC_OUTPUT_OBJ) {
     2078        /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
     2079        tcc_add_runtime(s1);
     2080        resolve_common_syms(s1);
     2081
     2082        if (!s1->static_link) {
     2083            if (file_type == TCC_OUTPUT_EXE) {
     2084                char *ptr;
     2085                /* allow override the dynamic loader */
     2086                const char *elfint = getenv("LD_SO");
     2087                if (elfint == NULL)
     2088                    elfint = DEFAULT_ELFINTERP(s1);
     2089                /* add interpreter section only if executable */
     2090                interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
     2091                interp->sh_addralign = 1;
     2092                ptr = section_ptr_add(interp, 1 + strlen(elfint));
     2093                strcpy(ptr, elfint);
     2094            }
     2095
     2096            /* add dynamic symbol table */
     2097            s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
     2098                                    ".dynstr",
     2099                                    ".hash", SHF_ALLOC);
     2100            dynstr = s1->dynsym->link;
     2101
     2102            /* add dynamic section */
     2103            dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
     2104                                  SHF_ALLOC | SHF_WRITE);
     2105            dynamic->link = dynstr;
     2106            dynamic->sh_entsize = sizeof(ElfW(Dyn));
     2107
     2108            build_got(s1);
     2109
     2110            if (file_type == TCC_OUTPUT_EXE) {
     2111                bind_exe_dynsyms(s1);
     2112                if (s1->nb_errors)
     2113                    goto the_end;
     2114                bind_libs_dynsyms(s1);
     2115            } else {
     2116                /* shared library case: simply export all global symbols */
     2117                export_global_syms(s1);
     2118            }
     2119        }
     2120        build_got_entries(s1);
     2121    }
     2122
     2123    /* we add a section for symbols */
     2124    strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
     2125    put_elf_str(strsec, "");
     2126
     2127    /* Allocate strings for section names */
     2128    textrel = alloc_sec_names(s1, file_type, strsec);
     2129
     2130    if (dynamic) {
     2131        /* add a list of needed dlls */
     2132        for(i = 0; i < s1->nb_loaded_dlls; i++) {
     2133            DLLReference *dllref = s1->loaded_dlls[i];
     2134            if (dllref->level == 0)
     2135                put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
     2136        }
     2137
     2138        if (s1->rpath)
     2139            put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
     2140                   put_elf_str(dynstr, s1->rpath));
     2141
     2142        if (file_type == TCC_OUTPUT_DLL) {
     2143            if (s1->soname)
     2144                put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
     2145            /* XXX: currently, since we do not handle PIC code, we
     2146               must relocate the readonly segments */
     2147            if (textrel)
     2148                put_dt(dynamic, DT_TEXTREL, 0);
     2149        }
     2150
     2151        if (s1->symbolic)
     2152            put_dt(dynamic, DT_SYMBOLIC, 0);
     2153
     2154        dyninf.dynamic = dynamic;
     2155        dyninf.dynstr = dynstr;
     2156        /* remember offset and reserve space for 2nd call below */
     2157        dyninf.data_offset = dynamic->data_offset;
     2158        fill_dynamic(s1, &dyninf);
     2159        dynamic->sh_size = dynamic->data_offset;
     2160        dynstr->sh_size = dynstr->data_offset;
     2161    }
     2162
     2163    /* compute number of program headers */
     2164    if (file_type == TCC_OUTPUT_OBJ)
     2165        phnum = 0;
     2166    else if (file_type == TCC_OUTPUT_DLL)
     2167        phnum = 3;
     2168    else if (s1->static_link)
     2169        phnum = 2;
     2170    else
     2171        phnum = 5;
     2172
     2173    /* allocate program segment headers */
     2174    phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
     2175
     2176    /* compute number of sections */
     2177    shnum = s1->nb_sections;
     2178
     2179    /* this array is used to reorder sections in the output file */
     2180    sec_order = tcc_malloc(sizeof(int) * shnum);
     2181    sec_order[0] = 0;
     2182
     2183    /* compute section to program header mapping */
     2184    file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
     2185                                  sec_order);
     2186
     2187    /* Fill remaining program header and finalize relocation related to dynamic
     2188       linking. */
     2189    if (file_type != TCC_OUTPUT_OBJ) {
     2190        fill_unloadable_phdr(phdr, phnum, interp, dynamic);
     2191        if (dynamic) {
     2192            dynamic->data_offset = dyninf.data_offset;
     2193            fill_dynamic(s1, &dyninf);
     2194
     2195            /* put in GOT the dynamic section address and relocate PLT */
     2196            write32le(s1->got->data, dynamic->sh_addr);
     2197            if (file_type == TCC_OUTPUT_EXE
     2198                || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
     2199                relocate_plt(s1);
     2200
     2201            /* relocate symbols in .dynsym now that final addresses are known */
     2202            for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
     2203                if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
     2204                    /* do symbol relocation */
     2205                    sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
    22822206                }
    2283                 size = s->sh_size;
    2284                 fwrite(s->data, 1, size, f);
    2285                 offset += size;
    2286             }
    2287         }
    2288 
    2289         /* output section headers */
    2290         while (offset < ehdr.e_shoff) {
    2291             fputc(0, f);
    2292             offset++;
    2293         }
    2294    
    2295         for(i=0;i<s1->nb_sections;i++) {
    2296             sh = &shdr;
    2297             memset(sh, 0, sizeof(ElfW(Shdr)));
    2298             s = s1->sections[i];
    2299             if (s) {
    2300                 sh->sh_name = s->sh_name;
    2301                 sh->sh_type = s->sh_type;
    2302                 sh->sh_flags = s->sh_flags;
    2303                 sh->sh_entsize = s->sh_entsize;
    2304                 sh->sh_info = s->sh_info;
    2305                 if (s->link)
    2306                     sh->sh_link = s->link->sh_num;
    2307                 sh->sh_addralign = s->sh_addralign;
    2308                 sh->sh_addr = s->sh_addr;
    2309                 sh->sh_offset = s->sh_offset;
    2310                 sh->sh_size = s->sh_size;
    2311             }
    2312             fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
    2313         }
    2314     } else {
    2315         tcc_output_binary(s1, f, section_order);
    2316     }
    2317     fclose(f);
    2318 
    2319     ret = 0;
     2207            }
     2208        }
     2209
     2210        /* if building executable or DLL, then relocate each section
     2211           except the GOT which is already relocated */
     2212        ret = final_sections_reloc(s1);
     2213        if (ret)
     2214            goto the_end;
     2215        tidy_section_headers(s1, sec_order);
     2216
     2217        /* Perform relocation to GOT or PLT entries */
     2218        if (file_type == TCC_OUTPUT_EXE && s1->static_link)
     2219            fill_got(s1);
     2220        else if (s1->got)
     2221            fill_local_got_entries(s1);
     2222    }
     2223
     2224    /* Create the ELF file with name 'filename' */
     2225    ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
     2226    s1->nb_sections = shnum;
    23202227 the_end:
    2321     tcc_free(s1->symtab_to_dynsym);
    2322     tcc_free(section_order);
     2228    tcc_free(sec_order);
    23232229    tcc_free(phdr);
    2324     tcc_free(s1->sym_attrs);
    23252230    return ret;
    23262231}
     
    23342239    } else
    23352240#endif
    2336     {
    23372241        ret = elf_output_file(s, filename);
    2338     }
    23392242    return ret;
    23402243}
     
    23572260} SectionMergeInfo;
    23582261
     2262ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
     2263{
     2264    int size = read(fd, h, sizeof *h);
     2265    if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
     2266        if (h->e_type == ET_REL)
     2267            return AFF_BINTYPE_REL;
     2268        if (h->e_type == ET_DYN)
     2269            return AFF_BINTYPE_DYN;
     2270    } else if (size >= 8) {
     2271        if (0 == memcmp(h, ARMAG, 8))
     2272            return AFF_BINTYPE_AR;
     2273#ifdef TCC_TARGET_COFF
     2274        if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
     2275            return AFF_BINTYPE_C67;
     2276#endif
     2277    }
     2278    return 0;
     2279}
     2280
    23592281/* load an object file and merge it with current files */
    23602282/* XXX: handle correctly stab (debug) info */
    2361 ST_FUNC int tcc_load_object_file(TCCState *s1, 
     2283ST_FUNC int tcc_load_object_file(TCCState *s1,
    23622284                                int fd, unsigned long file_offset)
    2363 { 
     2285{
    23642286    ElfW(Ehdr) ehdr;
    23652287    ElfW(Shdr) *shdr, *sh;
    2366     int size, i, j, offset, offseti, nb_syms, sym_index, ret;
     2288    int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
    23672289    unsigned char *strsec, *strtab;
    23682290    int *old_to_new_syms;
     
    23702292    SectionMergeInfo *sm_table, *sm;
    23712293    ElfW(Sym) *sym, *symtab;
    2372     ElfW_Rel *rel, *rel_end;
     2294    ElfW_Rel *rel;
    23732295    Section *s;
    23742296
     
    23782300    stab_index = stabstr_index = 0;
    23792301
    2380     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
    2381         goto fail1;
    2382     if (ehdr.e_ident[0] != ELFMAG0 ||
    2383         ehdr.e_ident[1] != ELFMAG1 ||
    2384         ehdr.e_ident[2] != ELFMAG2 ||
    2385         ehdr.e_ident[3] != ELFMAG3)
    2386         goto fail1;
    2387     /* test if object file */
    2388     if (ehdr.e_type != ET_REL)
     2302    lseek(fd, file_offset, SEEK_SET);
     2303    if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
    23892304        goto fail1;
    23902305    /* test CPU specific stuff */
     
    23962311    }
    23972312    /* read sections */
    2398     shdr = load_data(fd, file_offset + ehdr.e_shoff, 
     2313    shdr = load_data(fd, file_offset + ehdr.e_shoff,
    23992314                     sizeof(ElfW(Shdr)) * ehdr.e_shnum);
    24002315    sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
    2401    
     2316
    24022317    /* load section names */
    24032318    sh = &shdr[ehdr.e_shstrndx];
     
    24092324    strtab = NULL;
    24102325    nb_syms = 0;
     2326    seencompressed = 0;
    24112327    for(i = 1; i < ehdr.e_shnum; i++) {
    24122328        sh = &shdr[i];
     
    24262342            strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
    24272343        }
    2428     }
    2429        
     2344        if (sh->sh_flags & SHF_COMPRESSED)
     2345            seencompressed = 1;
     2346    }
     2347
    24302348    /* now examine each section and try to merge its content with the
    24312349       ones in memory */
     
    24352353            continue;
    24362354        sh = &shdr[i];
    2437         sh_name = strsec + sh->sh_name;
     2355        sh_name = (char *) strsec + sh->sh_name;
    24382356        /* ignore sections types we do not handle */
    24392357        if (sh->sh_type != SHT_PROGBITS &&
    2440             sh->sh_type != SHT_RELX && 
     2358            sh->sh_type != SHT_RELX &&
    24412359#ifdef TCC_ARM_EABI
    24422360            sh->sh_type != SHT_ARM_EXIDX &&
    24432361#endif
    2444             sh->sh_type != SHT_NOBITS && 
     2362            sh->sh_type != SHT_NOBITS &&
    24452363            sh->sh_type != SHT_PREINIT_ARRAY &&
    24462364            sh->sh_type != SHT_INIT_ARRAY &&
     
    24492367            )
    24502368            continue;
     2369        if (seencompressed
     2370            && (!strncmp(sh_name, ".debug_", sizeof(".debug_")-1)
     2371                || (sh->sh_type == SHT_RELX
     2372                    && !strncmp((char*)strsec + shdr[sh->sh_info].sh_name,
     2373                                ".debug_", sizeof(".debug_")-1))))
     2374          continue;
    24512375        if (sh->sh_addralign < 1)
    24522376            sh->sh_addralign = 1;
     
    24552379            s = s1->sections[j];
    24562380            if (!strcmp(s->name, sh_name)) {
    2457                 if (!strncmp(sh_name, ".gnu.linkonce", 
     2381                if (!strncmp(sh_name, ".gnu.linkonce",
    24582382                             sizeof(".gnu.linkonce") - 1)) {
    24592383                    /* if a 'linkonce' section is already present, we
     
    24692393        }
    24702394        /* not found: create new section */
    2471         s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
     2395        s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
    24722396        /* take as much info as possible from the section. sh_link and
    24732397           sh_info will be updated later */
     
    25142438    }
    25152439
    2516     /* //gr relocate stab strings */
     2440    /* gr relocate stab strings */
    25172441    if (stab_index && stabstr_index) {
    25182442        Stab_Sym *a, *b;
     
    25222446        b = (Stab_Sym *)(s->data + s->data_offset);
    25232447        o = sm_table[stabstr_index].offset;
    2524         while (a < b) 
     2448        while (a < b)
    25252449            a->n_strx += o, a++;
    25262450    }
     
    25562480                   correct relocations */
    25572481                if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
    2558                     name = strtab + sym->st_name;
     2482                    name = (char *) strtab + sym->st_name;
    25592483                    sym_index = find_elf_sym(symtab_section, name);
    25602484                    if (sym_index)
     
    25722496        }
    25732497        /* add symbol */
    2574         name = strtab + sym->st_name;
    2575         sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
    2576                                 sym->st_info, sym->st_other, 
     2498        name = (char *) strtab + sym->st_name;
     2499        sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
     2500                                sym->st_info, sym->st_other,
    25772501                                sym->st_shndx, name);
    25782502        old_to_new_syms[i] = sym_index;
     
    25902514            /* take relocation offset information */
    25912515            offseti = sm_table[sh->sh_info].offset;
    2592             rel_end = (ElfW_Rel *)(s->data + s->data_offset);
    2593             for(rel = (ElfW_Rel *)(s->data + offset);
    2594                 rel < rel_end;
    2595                 rel++) {
     2516            for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
    25962517                int type;
    25972518                unsigned sym_index;
     
    26242545                   instructions. Other case of instructions referencing a PLT
    26252546                   entry require to add a Thumb stub before the PLT entry to
    2626                    switch to ARM mode. We set bit 0 of the got offset of a
    2627                    symbol to indicate such a case. */
     2547                   switch to ARM mode. We set bit plt_thumb_stub of the
     2548                   attribute of a symbol to indicate such a case. */
    26282549                if (type == R_ARM_THM_JUMP24)
    2629                     alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;
     2550                    get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
    26302551#endif
    26312552            }
     
    26352556        }
    26362557    }
    2637    
     2558
    26382559    ret = 0;
    26392560 the_end:
     
    26622583}
    26632584
     2585static long get_be64(const uint8_t *b)
     2586{
     2587  long long ret = get_be32(b);
     2588  ret = (ret << 32) | (unsigned)get_be32(b+4);
     2589  return (long)ret;
     2590}
     2591
    26642592/* load only the objects which resolve undefined symbols */
    2665 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
    2666 {
    2667     int i, bound, nsyms, sym_index, off, ret;
     2593static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
     2594{
     2595    long i, bound, nsyms, sym_index, off, ret;
    26682596    uint8_t *data;
    26692597    const char *ar_names, *p;
     
    26742602    if (read(fd, data, size) != size)
    26752603        goto fail;
    2676     nsyms = get_be32(data);
    2677     ar_index = data + 4;
    2678     ar_names = ar_index + nsyms * 4;
     2604    nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
     2605    ar_index = data + entrysize;
     2606    ar_names = (char *) ar_index + nsyms * entrysize;
    26792607
    26802608    do {
     
    26852613                sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
    26862614                if(sym->st_shndx == SHN_UNDEF) {
    2687                     off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
    2688 #if 0
    2689                     printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
    2690 #endif
     2615                    off = (entrysize == 4
     2616                           ? get_be32(ar_index + i * 4)
     2617                           : get_be64(ar_index + i * 8))
     2618                          + sizeof(ArchiveHeader);
    26912619                    ++bound;
    2692                     lseek(fd, off, SEEK_SET);
    26932620                    if(tcc_load_object_file(s1, fd, off) < 0) {
    26942621                    fail:
     
    27182645    /* skip magic which was already checked */
    27192646    read(fd, magic, sizeof(magic));
    2720    
     2647
    27212648    for(;;) {
    27222649        len = read(fd, &hdr, sizeof(hdr));
     
    27362663        }
    27372664        ar_name[i + 1] = '\0';
    2738         //        printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
    27392665        file_offset = lseek(fd, 0, SEEK_CUR);
    27402666        /* align to even */
     
    27432669            /* coff symbol table : we handle it */
    27442670            if(s1->alacarte_link)
    2745                 return tcc_load_alacarte(s1, fd, size);
    2746         } else if (!strcmp(ar_name, "//") ||
    2747                    !strcmp(ar_name, "__.SYMDEF") ||
    2748                    !strcmp(ar_name, "__.SYMDEF/") ||
    2749                    !strcmp(ar_name, "ARFILENAMES/")) {
    2750             /* skip symbol table or archive names */
     2671                return tcc_load_alacarte(s1, fd, size, 4);
     2672        } else if (!strcmp(ar_name, "/SYM64/")) {
     2673            if(s1->alacarte_link)
     2674                return tcc_load_alacarte(s1, fd, size, 8);
    27512675        } else {
    2752             if (tcc_load_object_file(s1, fd, file_offset) < 0)
    2753                 return -1;
     2676            ElfW(Ehdr) ehdr;
     2677            if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
     2678                if (tcc_load_object_file(s1, fd, file_offset) < 0)
     2679                    return -1;
     2680            }
    27542681        }
    27552682        lseek(fd, file_offset + size, SEEK_SET);
     
    27632690   the generated ELF file) */
    27642691ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
    2765 { 
     2692{
    27662693    ElfW(Ehdr) ehdr;
    27672694    ElfW(Shdr) *shdr, *sh, *sh1;
     
    27722699    const char *name, *soname;
    27732700    DLLReference *dllref;
    2774    
     2701
    27752702    read(fd, &ehdr, sizeof(ehdr));
    27762703
     
    28072734        }
    28082735    }
    2809    
     2736
    28102737    /* compute the real library name */
    28112738    soname = tcc_basename(filename);
    2812        
     2739
    28132740    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
    28142741        if (dt->d_tag == DT_SONAME) {
    2815             soname = dynstr + dt->d_un.d_val;
     2742            soname = (char *) dynstr + dt->d_un.d_val;
    28162743        }
    28172744    }
     
    28282755        }
    28292756    }
    2830    
    2831     //    printf("loading dll '%s'\n", soname);
    28322757
    28332758    /* add the dll and its level */
     
    28352760    dllref->level = level;
    28362761    strcpy(dllref->name, soname);
    2837     dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
     2762    dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
    28382763
    28392764    /* add dynamic symbols in dynsym_section */
     
    28422767        if (sym_bind == STB_LOCAL)
    28432768            continue;
    2844         name = dynstr + sym->st_name;
    2845         add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
     2769        name = (char *) dynstr + sym->st_name;
     2770        set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
    28462771                    sym->st_info, sym->st_other, sym->st_shndx, name);
    28472772    }
     
    28512776        switch(dt->d_tag) {
    28522777        case DT_NEEDED:
    2853             name = dynstr + dt->d_un.d_val;
     2778            name = (char *) dynstr + dt->d_un.d_val;
    28542779            for(j = 0; j < s1->nb_loaded_dlls; j++) {
    28552780                dllref = s1->loaded_dlls[j];
     
    29062831        }
    29072832        break;
     2833    case '\\':
     2834        ch = handle_eob();
     2835        if (ch != '\\')
     2836            goto redo;
     2837        /* fall through */
    29082838    /* case 'a' ... 'z': */
    29092839    case 'a':
     
    29612891       case 'Z':
    29622892    case '_':
    2963     case '\\':
    29642893    case '.':
    29652894    case '$':
     
    29892918        break;
    29902919    }
    2991 #if 0
    2992     printf("tok=%c %d\n", c, c);
    2993     if (c == LD_TOK_NAME)
    2994         printf("  name=%s\n", name);
    2995 #endif
    29962920    return c;
    29972921}
     
    29992923static int ld_add_file(TCCState *s1, const char filename[])
    30002924{
    3001     int ret;
    3002 
    3003     ret = tcc_add_file_internal(s1, filename, 0);
    3004     if (ret)
    3005         ret = tcc_add_dll(s1, filename, 0);
    3006     return ret;
     2925    if (filename[0] == '/') {
     2926        if (CONFIG_SYSROOT[0] == '\0'
     2927            && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
     2928            return 0;
     2929        filename = tcc_basename(filename);
     2930    }
     2931    return tcc_add_dll(s1, filename, 0);
    30072932}
    30082933
     
    30662991                if (group) {
    30672992                    /* Add the filename *and* the libname to avoid future conversions */
    3068                     dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
     2993                    dynarray_add(&libs, &nblibs, tcc_strdup(filename));
    30692994                    if (libname[0] != '\0')
    3070                         dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
     2995                        dynarray_add(&libs, &nblibs, tcc_strdup(libname));
    30712996                }
    30722997            }
     
    30973022    char filename[1024];
    30983023    int t, ret;
    3099    
    3100     ch = file->buf_ptr[0];
     3024
    31013025    ch = handle_eob();
    31023026    for(;;) {
     
    31323056    return 0;
    31333057}
    3134 #endif /* ndef TCC_TARGET_PE */
     3058#endif /* !TCC_TARGET_PE */
Note: See TracChangeset for help on using the changeset viewer.