Subversion Repositories Kolibri OS

Rev

Rev 6429 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  *  ELF file handling for TCC
  3.  *
  4.  *  Copyright (c) 2001-2004 Fabrice Bellard
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with this library; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  */
  20.  
  21. #include "libtcc.h"
  22. #include "tcc.h"
  23.  
  24. /* Define this to get some debug output during relocation processing.  */
  25. #undef DEBUG_RELOC
  26.  
  27. /* XXX: avoid static variable */
  28. static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
  29.  
  30. ST_FUNC int put_elf_str(Section *s, const char *sym)
  31. {
  32.     int offset, len;
  33.     char *ptr;
  34.  
  35.     len = strlen(sym) + 1;
  36.     offset = s->data_offset;
  37.     ptr = section_ptr_add(s, len);
  38.     memcpy(ptr, sym, len);
  39.     return offset;
  40. }
  41.  
  42. /* elf symbol hashing function */
  43. static unsigned long elf_hash(const unsigned char *name)
  44. {
  45.     unsigned long h = 0, g;
  46.  
  47.     while (*name) {
  48.         h = (h << 4) + *name++;
  49.         g = h & 0xf0000000;
  50.         if (g)
  51.             h ^= g >> 24;
  52.         h &= ~g;
  53.     }
  54.     return h;
  55. }
  56.  
  57. /* rebuild hash table of section s */
  58. /* NOTE: we do factorize the hash table code to go faster */
  59. static void rebuild_hash(Section *s, unsigned int nb_buckets)
  60. {
  61.     ElfW(Sym) *sym;
  62.     int *ptr, *hash, nb_syms, sym_index, h;
  63.     unsigned char *strtab;
  64.  
  65.     strtab = s->link->data;
  66.     nb_syms = s->data_offset / sizeof(ElfW(Sym));
  67.  
  68.     s->hash->data_offset = 0;
  69.     ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
  70.     ptr[0] = nb_buckets;
  71.     ptr[1] = nb_syms;
  72.     ptr += 2;
  73.     hash = ptr;
  74.     memset(hash, 0, (nb_buckets + 1) * sizeof(int));
  75.     ptr += nb_buckets + 1;
  76.  
  77.     sym = (ElfW(Sym) *)s->data + 1;
  78.     for(sym_index = 1; sym_index < nb_syms; sym_index++) {
  79.         if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
  80.             h = elf_hash(strtab + sym->st_name) % nb_buckets;
  81.             *ptr = hash[h];
  82.             hash[h] = sym_index;
  83.         } else {
  84.             *ptr = 0;
  85.         }
  86.         ptr++;
  87.         sym++;
  88.     }
  89. }
  90.  
  91. /* return the symbol number */
  92. ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
  93.     int info, int other, int shndx, const char *name)
  94. {
  95.     int name_offset, sym_index;
  96.     int nbuckets, h;
  97.     ElfW(Sym) *sym;
  98.     Section *hs;
  99.  
  100.     sym = section_ptr_add(s, sizeof(ElfW(Sym)));
  101.     if (name)
  102.         name_offset = put_elf_str(s->link, name);
  103.     else
  104.         name_offset = 0;
  105.     /* XXX: endianness */
  106.     sym->st_name = name_offset;
  107.     sym->st_value = value;
  108.     sym->st_size = size;
  109.     sym->st_info = info;
  110.     sym->st_other = other;
  111.     sym->st_shndx = shndx;
  112.     sym_index = sym - (ElfW(Sym) *)s->data;
  113.     hs = s->hash;
  114.     if (hs) {
  115.         int *ptr, *base;
  116.         ptr = section_ptr_add(hs, sizeof(int));
  117.         base = (int *)hs->data;
  118.         /* only add global or weak symbols */
  119.         if (ELFW(ST_BIND)(info) != STB_LOCAL) {
  120.             /* add another hashing entry */
  121.             nbuckets = base[0];
  122.             h = elf_hash((unsigned char *) name) % nbuckets;
  123.             *ptr = base[2 + h];
  124.             base[2 + h] = sym_index;
  125.             base[1]++;
  126.             /* we resize the hash table */
  127.             hs->nb_hashed_syms++;
  128.             if (hs->nb_hashed_syms > 2 * nbuckets) {
  129.                 rebuild_hash(s, 2 * nbuckets);
  130.             }
  131.         } else {
  132.             *ptr = 0;
  133.             base[1]++;
  134.         }
  135.     }
  136.     return sym_index;
  137. }
  138.  
  139. /* find global ELF symbol 'name' and return its index. Return 0 if not
  140.    found. */
  141. ST_FUNC int find_elf_sym(Section *s, const char *name)
  142. {
  143.     ElfW(Sym) *sym;
  144.     Section *hs;
  145.     int nbuckets, sym_index, h;
  146.     const char *name1;
  147.  
  148.     hs = s->hash;
  149.     if (!hs)
  150.         return 0;
  151.     nbuckets = ((int *)hs->data)[0];
  152.     h = elf_hash((unsigned char *) name) % nbuckets;
  153.     sym_index = ((int *)hs->data)[2 + h];
  154.     while (sym_index != 0) {
  155.         sym = &((ElfW(Sym) *)s->data)[sym_index];
  156.         name1 = (char *) s->link->data + sym->st_name;
  157.         if (!strcmp(name, name1))
  158.             return sym_index;
  159.         sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
  160.     }
  161.     return 0;
  162. }
  163.  
  164. /* return elf symbol value, signal error if 'err' is nonzero */
  165. ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
  166. {
  167.     int sym_index;
  168.     ElfW(Sym) *sym;
  169.  
  170.     sym_index = find_elf_sym(s->symtab, name);
  171.     sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
  172.     if (!sym_index || sym->st_shndx == SHN_UNDEF) {
  173.         if (err)
  174.             tcc_error("%s not defined", name);
  175.         return 0;
  176.     }
  177.     return sym->st_value;
  178. }
  179.  
  180. /* return elf symbol value */
  181. LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
  182. {
  183.     return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
  184. }
  185.  
  186. #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE || defined TCC_TARGET_MEOS
  187. /* return elf symbol value or error */
  188. ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
  189. {
  190.     return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
  191. }
  192. #endif
  193.  
  194. /* add an elf symbol : check if it is already defined and patch
  195.    it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
  196. ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
  197.                        int info, int other, int sh_num, const char *name)
  198. {
  199.     ElfW(Sym) *esym;
  200.     int sym_bind, sym_index, sym_type, esym_bind;
  201.     unsigned char sym_vis, esym_vis, new_vis;
  202.  
  203.     sym_bind = ELFW(ST_BIND)(info);
  204.     sym_type = ELFW(ST_TYPE)(info);
  205.     sym_vis = ELFW(ST_VISIBILITY)(other);
  206.  
  207.     if (sym_bind != STB_LOCAL) {
  208.         /* we search global or weak symbols */
  209.         sym_index = find_elf_sym(s, name);
  210.         if (!sym_index)
  211.             goto do_def;
  212.         esym = &((ElfW(Sym) *)s->data)[sym_index];
  213.         if (esym->st_shndx != SHN_UNDEF) {
  214.             esym_bind = ELFW(ST_BIND)(esym->st_info);
  215.             /* propagate the most constraining visibility */
  216.             /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
  217.             esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
  218.             if (esym_vis == STV_DEFAULT) {
  219.                 new_vis = sym_vis;
  220.             } else if (sym_vis == STV_DEFAULT) {
  221.                 new_vis = esym_vis;
  222.             } else {
  223.                 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
  224.             }
  225.             esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
  226.                              | new_vis;
  227.             other = esym->st_other; /* in case we have to patch esym */
  228.             if (sh_num == SHN_UNDEF) {
  229.                 /* ignore adding of undefined symbol if the
  230.                    corresponding symbol is already defined */
  231.             } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
  232.                 /* global overrides weak, so patch */
  233.                 goto do_patch;
  234.             } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
  235.                 /* weak is ignored if already global */
  236.             } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
  237.                 /* keep first-found weak definition, ignore subsequents */
  238.             } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
  239.                 /* ignore hidden symbols after */
  240.             } else if (esym->st_shndx == SHN_COMMON
  241.                     && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) {
  242.                 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
  243.                    No idea if this is the correct solution ... */
  244.                 goto do_patch;
  245.             } else if (s == tcc_state->dynsymtab_section) {
  246.                 /* we accept that two DLL define the same symbol */
  247.             } else {
  248. #if 0
  249.                 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
  250.                        sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
  251. #endif
  252.                 tcc_error_noabort("'%s' defined twice... may be -fcommon is needed?", name);
  253.             }
  254.         } else {
  255.         do_patch:
  256.             esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
  257.             esym->st_shndx = sh_num;
  258.             new_undef_sym = 1;
  259.             esym->st_value = value;
  260.             esym->st_size = size;
  261.             esym->st_other = other;
  262.         }
  263.     } else {
  264.     do_def:
  265.         sym_index = put_elf_sym(s, value, size,
  266.                                 ELFW(ST_INFO)(sym_bind, sym_type), other,
  267.                                 sh_num, name);
  268.     }
  269.     return sym_index;
  270. }
  271.  
  272. /* put relocation */
  273. ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
  274.                             int type, int symbol, addr_t addend)
  275. {
  276.     char buf[256];
  277.     Section *sr;
  278.     ElfW_Rel *rel;
  279.  
  280.     sr = s->reloc;
  281.     if (!sr) {
  282.         /* if no relocation section, create it */
  283.         snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
  284.         /* if the symtab is allocated, then we consider the relocation
  285.            are also */
  286.         sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
  287.         sr->sh_entsize = sizeof(ElfW_Rel);
  288.         sr->link = symtab;
  289.         sr->sh_info = s->sh_num;
  290.         s->reloc = sr;
  291.     }
  292.     rel = section_ptr_add(sr, sizeof(ElfW_Rel));
  293.     rel->r_offset = offset;
  294.     rel->r_info = ELFW(R_INFO)(symbol, type);
  295. #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
  296.     rel->r_addend = addend;
  297. #else
  298.     if (addend)
  299.         tcc_error("non-zero addend on REL architecture");
  300. #endif
  301. }
  302.  
  303. ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
  304.                            int type, int symbol)
  305. {
  306.     put_elf_reloca(symtab, s, offset, type, symbol, 0);
  307. }
  308.  
  309. /* put stab debug information */
  310.  
  311. ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
  312.                       unsigned long value)
  313. {
  314.     Stab_Sym *sym;
  315.  
  316.     sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
  317.     if (str) {
  318.         sym->n_strx = put_elf_str(stabstr_section, str);
  319.     } else {
  320.         sym->n_strx = 0;
  321.     }
  322.     sym->n_type = type;
  323.     sym->n_other = other;
  324.     sym->n_desc = desc;
  325.     sym->n_value = value;
  326. }
  327.  
  328. ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
  329.                         unsigned long value, Section *sec, int sym_index)
  330. {
  331.     put_stabs(str, type, other, desc, value);
  332.     put_elf_reloc(symtab_section, stab_section,
  333.                   stab_section->data_offset - sizeof(unsigned int),
  334.                   R_DATA_32, sym_index);
  335. }
  336.  
  337. ST_FUNC void put_stabn(int type, int other, int desc, int value)
  338. {
  339.     put_stabs(NULL, type, other, desc, value);
  340. }
  341.  
  342. ST_FUNC void put_stabd(int type, int other, int desc)
  343. {
  344.     put_stabs(NULL, type, other, desc, 0);
  345. }
  346.  
  347. /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
  348.    using variable <elem> */
  349. #define for_each_elem(sec, startoff, elem, type) \
  350.     for (elem = (type *) sec->data + startoff; \
  351.          elem < (type *) (sec->data + sec->data_offset); elem++)
  352.  
  353. /* In an ELF file symbol table, the local symbols must appear below
  354.    the global and weak ones. Since TCC cannot sort it while generating
  355.    the code, we must do it after. All the relocation tables are also
  356.    modified to take into account the symbol table sorting */
  357. static void sort_syms(TCCState *s1, Section *s)
  358. {
  359.     int *old_to_new_syms;
  360.     ElfW(Sym) *new_syms;
  361.     int nb_syms, i;
  362.     ElfW(Sym) *p, *q;
  363.     ElfW_Rel *rel;
  364.     Section *sr;
  365.     int type, sym_index;
  366.  
  367.     nb_syms = s->data_offset / sizeof(ElfW(Sym));
  368.     new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
  369.     old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
  370.  
  371.     /* first pass for local symbols */
  372.     p = (ElfW(Sym) *)s->data;
  373.     q = new_syms;
  374.     for(i = 0; i < nb_syms; i++) {
  375.         if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
  376.             old_to_new_syms[i] = q - new_syms;
  377.             *q++ = *p;
  378.         }
  379.         p++;
  380.     }
  381.     /* save the number of local symbols in section header */
  382.     s->sh_info = q - new_syms;
  383.  
  384.     /* then second pass for non local symbols */
  385.     p = (ElfW(Sym) *)s->data;
  386.     for(i = 0; i < nb_syms; i++) {
  387.         if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
  388.             old_to_new_syms[i] = q - new_syms;
  389.             *q++ = *p;
  390.         }
  391.         p++;
  392.     }
  393.  
  394.     /* we copy the new symbols to the old */
  395.     memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
  396.     tcc_free(new_syms);
  397.  
  398.     /* now we modify all the relocations */
  399.     for(i = 1; i < s1->nb_sections; i++) {
  400.         sr = s1->sections[i];
  401.         if (sr->sh_type == SHT_RELX && sr->link == s) {
  402.             for_each_elem(sr, 0, rel, ElfW_Rel) {
  403.                 sym_index = ELFW(R_SYM)(rel->r_info);
  404.                 type = ELFW(R_TYPE)(rel->r_info);
  405.                 sym_index = old_to_new_syms[sym_index];
  406.                 rel->r_info = ELFW(R_INFO)(sym_index, type);
  407.             }
  408.         }
  409.     }
  410.  
  411.     tcc_free(old_to_new_syms);
  412. }
  413.  
  414. /* relocate common symbols in the .bss section */
  415. ST_FUNC void relocate_common_syms(void)
  416. {
  417.     ElfW(Sym) *sym;
  418.     unsigned long offset, align;
  419.  
  420.     for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
  421.         if (sym->st_shndx == SHN_COMMON) {
  422.             /* align symbol */
  423.             align = sym->st_value;
  424.             offset = bss_section->data_offset;
  425.             offset = (offset + align - 1) & -align;
  426.             sym->st_value = offset;
  427.             sym->st_shndx = bss_section->sh_num;
  428.             offset += sym->st_size;
  429.             bss_section->data_offset = offset;
  430.         }
  431.     }
  432. }
  433.  
  434. /* relocate symbol table, resolve undefined symbols if do_resolve is
  435.    true and output error if undefined symbol. */
  436. ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
  437. {
  438.     ElfW(Sym) *sym, *esym;
  439.     int sym_bind, sh_num, sym_index;
  440.     const char *name;
  441.  
  442.     for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
  443.         sh_num = sym->st_shndx;
  444.         if (sh_num == SHN_UNDEF) {
  445.             name = (char *) strtab_section->data + sym->st_name;
  446.             /* Use ld.so to resolve symbol for us (for tcc -run) */
  447.             if (do_resolve) {
  448. #if defined TCC_IS_NATIVE && !defined _WIN32
  449.                 void *addr;
  450.                 name = (char *) symtab_section->link->data + sym->st_name;
  451.                 addr = resolve_sym(s1, name);
  452.                 if (addr) {
  453.                     sym->st_value = (addr_t)addr;
  454. #ifdef DEBUG_RELOC
  455.                     printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
  456. #endif
  457.                     goto found;
  458.                 }
  459. #endif
  460.             } else if (s1->dynsym) {
  461.                 /* if dynamic symbol exist, then use it */
  462.                 sym_index = find_elf_sym(s1->dynsym, name);
  463.                 if (sym_index) {
  464.                     esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
  465.                     sym->st_value = esym->st_value;
  466.                     goto found;
  467.                 }
  468.             }
  469.             /* XXX: _fp_hw seems to be part of the ABI, so we ignore
  470.                it */
  471.             if (!strcmp(name, "_fp_hw"))
  472.                 goto found;
  473.             /* only weak symbols are accepted to be undefined. Their
  474.                value is zero */
  475.             sym_bind = ELFW(ST_BIND)(sym->st_info);
  476.             if (sym_bind == STB_WEAK) {
  477.                 sym->st_value = 0;
  478.             } else {
  479.                 tcc_error_noabort("undefined symbol '%s'", name);
  480.             }
  481.         } else if (sh_num < SHN_LORESERVE) {
  482.             /* add section base */
  483.             sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
  484.         }
  485.     found: ;
  486.     }
  487. }
  488.  
  489. /* relocate a given section (CPU dependent) by applying the relocations
  490.    in the associated relocation section */
  491. ST_FUNC void relocate_section(TCCState *s1, Section *s)
  492. {
  493.     Section *sr = s->reloc;
  494.     ElfW_Rel *rel;
  495.     ElfW(Sym) *sym;
  496.     int type, sym_index;
  497.     unsigned char *ptr;
  498.     addr_t val, addr;
  499. #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
  500.     ElfW_Rel *qrel = (ElfW_Rel *) sr->data; /* ptr to next reloc entry reused */
  501.     int esym_index;
  502. #endif
  503.  
  504.     for_each_elem(sr, 0, rel, ElfW_Rel) {
  505.         ptr = s->data + rel->r_offset;
  506.  
  507.         sym_index = ELFW(R_SYM)(rel->r_info);
  508.         sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
  509.         val = sym->st_value;
  510. #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
  511.         val += rel->r_addend;
  512. #endif
  513.         type = ELFW(R_TYPE)(rel->r_info);
  514.         addr = s->sh_addr + rel->r_offset;
  515.  
  516.         /* CPU specific */
  517.         switch(type) {
  518. #if defined(TCC_TARGET_I386)
  519.         case R_386_32:
  520.             if (s1->output_type == TCC_OUTPUT_DLL) {
  521.                 esym_index = s1->symtab_to_dynsym[sym_index];
  522.                 qrel->r_offset = rel->r_offset;
  523.                 if (esym_index) {
  524.                     qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
  525.                     qrel++;
  526.                     break;
  527.                 } else {
  528.                     qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
  529.                     qrel++;
  530.                 }
  531.             }
  532.             write32le(ptr, read32le(ptr) + val);
  533.             break;
  534.         case R_386_PC32:
  535.             if (s1->output_type == TCC_OUTPUT_DLL) {
  536.                 /* DLL relocation */
  537.                 esym_index = s1->symtab_to_dynsym[sym_index];
  538.                 if (esym_index) {
  539.                     qrel->r_offset = rel->r_offset;
  540.                     qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
  541.                     qrel++;
  542.                     break;
  543.                 }
  544.             }
  545.             write32le(ptr, read32le(ptr) + val - addr);
  546.             break;
  547.         case R_386_PLT32:
  548.             write32le(ptr, read32le(ptr) + val - addr);
  549.             break;
  550.         case R_386_GLOB_DAT:
  551.         case R_386_JMP_SLOT:
  552.             write32le(ptr, val);
  553.             break;
  554.         case R_386_GOTPC:
  555.             write32le(ptr, read32le(ptr) + s1->got->sh_addr - addr);
  556.             break;
  557.         case R_386_GOTOFF:
  558.             write32le(ptr, read32le(ptr) + val - s1->got->sh_addr);
  559.             break;
  560.         case R_386_GOT32:
  561.         case R_386_GOT32X:
  562.             /* we load the got offset */
  563.             write32le(ptr, read32le(ptr) + s1->sym_attrs[sym_index].got_offset);
  564.             break;
  565.         case R_386_16:
  566.             if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
  567.             output_file:
  568.                 tcc_error("can only produce 16-bit binary files");
  569.             }
  570.             write16le(ptr, read16le(ptr) + val);
  571.             break;
  572.         case R_386_PC16:
  573.             if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
  574.                 goto output_file;
  575.             write16le(ptr, read16le(ptr) + val - addr);
  576.             break;
  577.         case R_386_RELATIVE:
  578.             /* do nothing */
  579.             break;
  580.         case R_386_COPY:
  581.             /* This reloction must copy initialized data from the library
  582.             to the program .bss segment. Currently made like for ARM
  583.             (to remove noise of defaukt case). Is this true?
  584.             */
  585.             break;
  586.         default:
  587.             fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n",
  588.                 type, (unsigned)addr, ptr, (unsigned)val);
  589.             break;
  590. #elif defined(TCC_TARGET_ARM)
  591.         case R_ARM_PC24:
  592.         case R_ARM_CALL:
  593.         case R_ARM_JUMP24:
  594.         case R_ARM_PLT32:
  595.             {
  596.                 int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
  597.                 x = (*(int *) ptr) & 0xffffff;
  598.                 if (sym->st_shndx == SHN_UNDEF)
  599.                     val = s1->plt->sh_addr;
  600. #ifdef DEBUG_RELOC
  601.                 printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
  602. #endif
  603.                 (*(int *)ptr) &= 0xff000000;
  604.                 if (x & 0x800000)
  605.                     x -= 0x1000000;
  606.                 x <<= 2;
  607.                 blx_avail = (TCC_ARM_VERSION >= 5);
  608.                 is_thumb = val & 1;
  609.                 is_bl = (*(unsigned *) ptr) >> 24 == 0xeb;
  610.                 is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
  611.                 x += val - addr;
  612. #ifdef DEBUG_RELOC
  613.                 printf (" newx=0x%x name=%s\n", x,
  614.                         (char *) symtab_section->link->data + sym->st_name);
  615. #endif
  616.                 h = x & 2;
  617.                 th_ko = (x & 3) && (!blx_avail || !is_call);
  618.                 if (th_ko || x >= 0x2000000 || x < -0x2000000)
  619.                     tcc_error("can't relocate value at %x,%d",addr, type);
  620.                 x >>= 2;
  621.                 x &= 0xffffff;
  622.                 /* Only reached if blx is avail and it is a call */
  623.                 if (is_thumb) {
  624.                     x |= h << 24;
  625.                     (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
  626.                 }
  627.                 (*(int *) ptr) |= x;
  628.             }
  629.             break;
  630.         /* Since these relocations only concern Thumb-2 and blx instruction was
  631.            introduced before Thumb-2, we can assume blx is available and not
  632.            guard its use */
  633.         case R_ARM_THM_PC22:
  634.         case R_ARM_THM_JUMP24:
  635.             {
  636.                 int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
  637.                 int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
  638.                 Section *plt;
  639.  
  640.                 /* weak reference */
  641.                 if (sym->st_shndx == SHN_UNDEF &&
  642.                     ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
  643.                     break;
  644.  
  645.                 /* Get initial offset */
  646.                 hi = (*(uint16_t *)ptr);
  647.                 lo = (*(uint16_t *)(ptr+2));
  648.                 s = (hi >> 10) & 1;
  649.                 j1 = (lo >> 13) & 1;
  650.                 j2 = (lo >> 11) & 1;
  651.                 i1 = (j1 ^ s) ^ 1;
  652.                 i2 = (j2 ^ s) ^ 1;
  653.                 imm10 = hi & 0x3ff;
  654.                 imm11 = lo & 0x7ff;
  655.                 x = (s << 24) | (i1 << 23) | (i2 << 22) |
  656.                     (imm10 << 12) | (imm11 << 1);
  657.                 if (x & 0x01000000)
  658.                     x -= 0x02000000;
  659.  
  660.                 /* Relocation infos */
  661.                 to_thumb = val & 1;
  662.                 plt = s1->plt;
  663.                 to_plt = (val >= plt->sh_addr) &&
  664.                          (val < plt->sh_addr + plt->data_offset);
  665.                 is_call = (type == R_ARM_THM_PC22);
  666.  
  667.                 /* Compute final offset */
  668.                 if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */
  669.                     x -= 4;
  670.                 x += val - addr;
  671.                 if (!to_thumb && is_call) {
  672.                     blx_bit = 0; /* bl -> blx */
  673.                     x = (x + 3) & -4; /* Compute offset from aligned PC */
  674.                 }
  675.  
  676.                 /* Check that relocation is possible
  677.                    * offset must not be out of range
  678.                    * if target is to be entered in arm mode:
  679.                      - bit 1 must not set
  680.                      - instruction must be a call (bl) or a jump to PLT */
  681.                 if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
  682.                     if (to_thumb || (val & 2) || (!is_call && !to_plt))
  683.                         tcc_error("can't relocate value at %x,%d",addr, type);
  684.  
  685.                 /* Compute and store final offset */
  686.                 s = (x >> 24) & 1;
  687.                 i1 = (x >> 23) & 1;
  688.                 i2 = (x >> 22) & 1;
  689.                 j1 = s ^ (i1 ^ 1);
  690.                 j2 = s ^ (i2 ^ 1);
  691.                 imm10 = (x >> 12) & 0x3ff;
  692.                 imm11 = (x >> 1) & 0x7ff;
  693.                 (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) |
  694.                                      (s << 10) | imm10);
  695.                 (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) |
  696.                                 (j1 << 13) | blx_bit | (j2 << 11) |
  697.                                 imm11);
  698.             }
  699.             break;
  700.         case R_ARM_MOVT_ABS:
  701.         case R_ARM_MOVW_ABS_NC:
  702.             {
  703.                 int x, imm4, imm12;
  704.                 if (type == R_ARM_MOVT_ABS)
  705.                     val >>= 16;
  706.                 imm12 = val & 0xfff;
  707.                 imm4 = (val >> 12) & 0xf;
  708.                 x = (imm4 << 16) | imm12;
  709.                 if (type == R_ARM_THM_MOVT_ABS)
  710.                     *(int *)ptr |= x;
  711.                 else
  712.                     *(int *)ptr += x;
  713.             }
  714.             break;
  715.         case R_ARM_THM_MOVT_ABS:
  716.         case R_ARM_THM_MOVW_ABS_NC:
  717.             {
  718.                 int x, i, imm4, imm3, imm8;
  719.                 if (type == R_ARM_THM_MOVT_ABS)
  720.                     val >>= 16;
  721.                 imm8 = val & 0xff;
  722.                 imm3 = (val >> 8) & 0x7;
  723.                 i = (val >> 11) & 1;
  724.                 imm4 = (val >> 12) & 0xf;
  725.                 x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4;
  726.                 if (type == R_ARM_THM_MOVT_ABS)
  727.                     *(int *)ptr |= x;
  728.                 else
  729.                     *(int *)ptr += x;
  730.             }
  731.             break;
  732.         case R_ARM_PREL31:
  733.             {
  734.                 int x;
  735.                 x = (*(int *)ptr) & 0x7fffffff;
  736.                 (*(int *)ptr) &= 0x80000000;
  737.                 x = (x * 2) / 2;
  738.                 x += val - addr;
  739.                 if((x^(x>>1))&0x40000000)
  740.                     tcc_error("can't relocate value at %x,%d",addr, type);
  741.                 (*(int *)ptr) |= x & 0x7fffffff;
  742.             }
  743.         case R_ARM_ABS32:
  744.             *(int *)ptr += val;
  745.             break;
  746.         case R_ARM_REL32:
  747.             *(int *)ptr += val - addr;
  748.             break;
  749.         case R_ARM_GOTPC:
  750.             *(int *)ptr += s1->got->sh_addr - addr;
  751.             break;
  752.         case R_ARM_GOTOFF:
  753.             *(int *)ptr += val - s1->got->sh_addr;
  754.             break;
  755.         case R_ARM_GOT32:
  756.             /* we load the got offset */
  757.             *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
  758.             break;
  759.         case R_ARM_COPY:
  760.             break;
  761.         case R_ARM_V4BX:
  762.             /* trade Thumb support for ARMv4 support */
  763.             if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10)
  764.                 *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
  765.             break;
  766.         case R_ARM_GLOB_DAT:
  767.         case R_ARM_JUMP_SLOT:
  768.             *(addr_t *)ptr = val;
  769.             break;
  770.         case R_ARM_NONE:
  771.             /* Nothing to do.  Normally used to indicate a dependency
  772.                on a certain symbol (like for exception handling under EABI).  */
  773.             break;
  774.         default:
  775.             fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
  776.                 type, (unsigned)addr, ptr, (unsigned)val);
  777.             break;
  778. #elif defined(TCC_TARGET_ARM64)
  779.         case R_AARCH64_ABS64:
  780.             write64le(ptr, val);
  781.             break;
  782.         case R_AARCH64_ABS32:
  783.             write32le(ptr, val);
  784.             break;
  785.         case R_AARCH64_MOVW_UABS_G0_NC:
  786.             write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
  787.                             (val & 0xffff) << 5));
  788.             break;
  789.         case R_AARCH64_MOVW_UABS_G1_NC:
  790.             write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
  791.                             (val >> 16 & 0xffff) << 5));
  792.             break;
  793.         case R_AARCH64_MOVW_UABS_G2_NC:
  794.             write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
  795.                             (val >> 32 & 0xffff) << 5));
  796.             break;
  797.         case R_AARCH64_MOVW_UABS_G3:
  798.             write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
  799.                             (val >> 48 & 0xffff) << 5));
  800.             break;
  801.         case R_AARCH64_ADR_PREL_PG_HI21: {
  802.             uint64_t off = (val >> 12) - (addr >> 12);
  803.             if ((off + ((uint64_t)1 << 20)) >> 21)
  804.                 tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
  805.             write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
  806.                             (off & 0x1ffffc) << 3 | (off & 3) << 29));
  807.             break;
  808.         }
  809.         case R_AARCH64_ADD_ABS_LO12_NC:
  810.             write32le(ptr, ((read32le(ptr) & 0xffc003ff) |
  811.                             (val & 0xfff) << 10));
  812.             break;
  813.         case R_AARCH64_JUMP26:
  814.         case R_AARCH64_CALL26:
  815.             /* This check must match the one in build_got_entries, testing
  816.                if we really need a PLT slot.  */
  817.             if (sym->st_shndx == SHN_UNDEF)
  818.                 /* We've put the PLT slot offset into r_addend when generating
  819.                    it, and that's what we must use as relocation value (adjusted
  820.                    by section offset of course).  */
  821.                 val = s1->plt->sh_addr + rel->r_addend;
  822. #ifdef DEBUG_RELOC
  823.             printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
  824.                     (char *) symtab_section->link->data + sym->st_name);
  825. #endif
  826.             if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
  827.               {
  828.                 tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val);
  829.               }
  830.             write32le(ptr, (0x14000000 |
  831.                             (uint32_t)(type == R_AARCH64_CALL26) << 31 |
  832.                             ((val - addr) >> 2 & 0x3ffffff)));
  833.             break;
  834.         case R_AARCH64_ADR_GOT_PAGE: {
  835.             uint64_t off =
  836.                 (((s1->got->sh_addr +
  837.                    s1->sym_attrs[sym_index].got_offset) >> 12) - (addr >> 12));
  838.             if ((off + ((uint64_t)1 << 20)) >> 21)
  839.                 tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");
  840.             write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
  841.                             (off & 0x1ffffc) << 3 | (off & 3) << 29));
  842.             break;
  843.         }
  844.         case R_AARCH64_LD64_GOT_LO12_NC:
  845.             write32le(ptr,
  846.                       ((read32le(ptr) & 0xfff803ff) |
  847.                        ((s1->got->sh_addr +
  848.                          s1->sym_attrs[sym_index].got_offset) & 0xff8) << 7));
  849.             break;
  850.         case R_AARCH64_COPY:
  851.             break;
  852.         case R_AARCH64_GLOB_DAT:
  853.         case R_AARCH64_JUMP_SLOT:
  854.             /* They don't need addend */
  855. #ifdef DEBUG_RELOC
  856.             printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
  857.                     val - rel->r_addend,
  858.                     (char *) symtab_section->link->data + sym->st_name);
  859. #endif
  860.             write64le(ptr, val - rel->r_addend);
  861.             break;
  862.         default:
  863.             fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
  864.                     type, (unsigned)addr, ptr, (unsigned)val);
  865.             break;
  866. #elif defined(TCC_TARGET_C67)
  867.         case R_C60_32:
  868.             *(int *)ptr += val;
  869.             break;
  870.         case R_C60LO16:
  871.             {
  872.                 uint32_t orig;
  873.  
  874.                 /* put the low 16 bits of the absolute address
  875.                    add to what is already there */
  876.  
  877.                 orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
  878.                 orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
  879.  
  880.                 /* patch both at once - assumes always in pairs Low - High */
  881.  
  882.                 *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |  (((val+orig)      & 0xffff) << 7);
  883.                 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
  884.             }
  885.             break;
  886.         case R_C60HI16:
  887.             break;
  888.         default:
  889.             fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
  890.                 type, (unsigned)addr, ptr, (unsigned)val);
  891.             break;
  892. #elif defined(TCC_TARGET_X86_64)
  893.         case R_X86_64_64:
  894.             if (s1->output_type == TCC_OUTPUT_DLL) {
  895.                 esym_index = s1->symtab_to_dynsym[sym_index];
  896.                 qrel->r_offset = rel->r_offset;
  897.                 if (esym_index) {
  898.                     qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64);
  899.                     qrel->r_addend = rel->r_addend;
  900.                     qrel++;
  901.                     break;
  902.                 } else {
  903.                     qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
  904.                     qrel->r_addend = read64le(ptr) + val;
  905.                     qrel++;
  906.                 }
  907.             }
  908.             write64le(ptr, read64le(ptr) + val);
  909.             break;
  910.         case R_X86_64_32:
  911.         case R_X86_64_32S:
  912.             if (s1->output_type == TCC_OUTPUT_DLL) {
  913.                 /* XXX: this logic may depend on TCC's codegen
  914.                    now TCC uses R_X86_64_32 even for a 64bit pointer */
  915.                 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
  916.                 /* Use sign extension! */
  917.                 qrel->r_addend = (int)read32le(ptr) + val;
  918.                 qrel++;
  919.             }
  920.             write32le(ptr, read32le(ptr) + val);
  921.             break;
  922.  
  923.         case R_X86_64_PC32:
  924.             if (s1->output_type == TCC_OUTPUT_DLL) {
  925.                 /* DLL relocation */
  926.                 esym_index = s1->symtab_to_dynsym[sym_index];
  927.                 if (esym_index) {
  928.                     qrel->r_offset = rel->r_offset;
  929.                     qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
  930.                     /* Use sign extension! */
  931.                     qrel->r_addend = (int)read32le(ptr);
  932.                     qrel++;
  933.                     break;
  934.                 }
  935.             }
  936.             goto plt32pc32;
  937.  
  938.         case R_X86_64_PLT32:
  939.             /* We've put the PLT slot offset into r_addend when generating
  940.                it, and that's what we must use as relocation value (adjusted
  941.                by section offset of course).  */
  942.             val = s1->plt->sh_addr + rel->r_addend;
  943.             /* fallthrough.  */
  944.  
  945.         plt32pc32:
  946.         {
  947.             long long diff;
  948.             diff = (long long)val - addr;
  949.             if (diff < -2147483648LL || diff > 2147483647LL) {
  950.                 tcc_error("internal error: relocation failed");
  951.             }
  952.             write32le(ptr, read32le(ptr) + diff);
  953.         }
  954.             break;
  955.         case R_X86_64_GLOB_DAT:
  956.         case R_X86_64_JUMP_SLOT:
  957.             /* They don't need addend */
  958.             write64le(ptr, val - rel->r_addend);
  959.             break;
  960.         case R_X86_64_GOTPCREL:
  961.         case R_X86_64_GOTPCRELX:
  962.         case R_X86_64_REX_GOTPCRELX:
  963.             write32le(ptr, read32le(ptr) +
  964.                       (s1->got->sh_addr - addr +
  965.                        s1->sym_attrs[sym_index].got_offset - 4));
  966.             break;
  967.         case R_X86_64_GOTTPOFF:
  968.             write32le(ptr, read32le(ptr) + val - s1->got->sh_addr);
  969.             break;
  970.         case R_X86_64_GOT32:
  971.             /* we load the got offset */
  972.             write32le(ptr, read32le(ptr) + s1->sym_attrs[sym_index].got_offset);
  973.             break;
  974. #else
  975. #error unsupported processor
  976. #endif
  977.         }
  978.     }
  979.     /* if the relocation is allocated, we change its symbol table */
  980.     if (sr->sh_flags & SHF_ALLOC)
  981.         sr->link = s1->dynsym;
  982. }
  983.  
  984. /* relocate relocation table in 'sr' */
  985. static void relocate_rel(TCCState *s1, Section *sr)
  986. {
  987.     Section *s;
  988.     ElfW_Rel *rel;
  989.  
  990.     s = s1->sections[sr->sh_info];
  991.     for_each_elem(sr, 0, rel, ElfW_Rel)
  992.         rel->r_offset += s->sh_addr;
  993. }
  994.  
  995. /* count the number of dynamic relocations so that we can reserve
  996.    their space */
  997. static int prepare_dynamic_rel(TCCState *s1, Section *sr)
  998. {
  999.     ElfW_Rel *rel;
  1000.     int sym_index, esym_index, type, count;
  1001.  
  1002.     count = 0;
  1003.     for_each_elem(sr, 0, rel, ElfW_Rel) {
  1004.         sym_index = ELFW(R_SYM)(rel->r_info);
  1005.         type = ELFW(R_TYPE)(rel->r_info);
  1006.         switch(type) {
  1007. #if defined(TCC_TARGET_I386)
  1008.         case R_386_32:
  1009. #elif defined(TCC_TARGET_X86_64)
  1010.         case R_X86_64_32:
  1011.         case R_X86_64_32S:
  1012.         case R_X86_64_64:
  1013. #endif
  1014.             count++;
  1015.             break;
  1016. #if defined(TCC_TARGET_I386)
  1017.         case R_386_PC32:
  1018. #elif defined(TCC_TARGET_X86_64)
  1019.         case R_X86_64_PC32:
  1020. #endif
  1021.             esym_index = s1->symtab_to_dynsym[sym_index];
  1022.             if (esym_index)
  1023.                 count++;
  1024.             break;
  1025.         default:
  1026.             break;
  1027.         }
  1028.     }
  1029.     if (count) {
  1030.         /* allocate the section */
  1031.         sr->sh_flags |= SHF_ALLOC;
  1032.         sr->sh_size = count * sizeof(ElfW_Rel);
  1033.     }
  1034.     return count;
  1035. }
  1036.  
  1037. static struct sym_attr *alloc_sym_attr(TCCState *s1, int index)
  1038. {
  1039.     int n;
  1040.     struct sym_attr *tab;
  1041.  
  1042.     if (index >= s1->nb_sym_attrs) {
  1043.         /* find immediately bigger power of 2 and reallocate array */
  1044.         n = 1;
  1045.         while (index >= n)
  1046.             n *= 2;
  1047.         tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
  1048.         s1->sym_attrs = tab;
  1049.         memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
  1050.                (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
  1051.         s1->nb_sym_attrs = n;
  1052.     }
  1053.     return &s1->sym_attrs[index];
  1054. }
  1055.  
  1056. static void build_got(TCCState *s1)
  1057. {
  1058.     unsigned char *ptr;
  1059.  
  1060.     /* if no got, then create it */
  1061.     s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
  1062.     s1->got->sh_entsize = 4;
  1063.     add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
  1064.                 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
  1065.     ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
  1066. #if PTR_SIZE == 4
  1067.     /* keep space for _DYNAMIC pointer, if present */
  1068.     write32le(ptr, 0);
  1069.     /* two dummy got entries */
  1070.     write32le(ptr + 4, 0);
  1071.     write32le(ptr + 8, 0);
  1072. #else
  1073.     /* keep space for _DYNAMIC pointer, if present */
  1074.     write32le(ptr, 0);
  1075.     write32le(ptr + 4, 0);
  1076.     /* two dummy got entries */
  1077.     write32le(ptr + 8, 0);
  1078.     write32le(ptr + 12, 0);
  1079.     write32le(ptr + 16, 0);
  1080.     write32le(ptr + 20, 0);
  1081. #endif
  1082. }
  1083.  
  1084. /* put a got or plt entry corresponding to a symbol in symtab_section. 'size'
  1085.    and 'info' can be modifed if more precise info comes from the DLL.
  1086.    Returns offset of GOT or PLT slot.  */
  1087. static unsigned long put_got_entry(TCCState *s1,
  1088.                                    int reloc_type, unsigned long size, int info,
  1089.                                    int sym_index)
  1090. {
  1091.     int index, need_plt_entry;
  1092.     const char *name;
  1093.     ElfW(Sym) *sym;
  1094.     unsigned long offset;
  1095.     int *ptr;
  1096.     struct sym_attr *symattr;
  1097.  
  1098.     if (!s1->got)
  1099.         build_got(s1);
  1100.  
  1101.     need_plt_entry =
  1102. #ifdef TCC_TARGET_X86_64
  1103.         (reloc_type == R_X86_64_JUMP_SLOT);
  1104. #elif defined(TCC_TARGET_I386)
  1105.         (reloc_type == R_386_JMP_SLOT);
  1106. #elif defined(TCC_TARGET_ARM)
  1107.         (reloc_type == R_ARM_JUMP_SLOT);
  1108. #elif defined(TCC_TARGET_ARM64)
  1109.         (reloc_type == R_AARCH64_JUMP_SLOT);
  1110. #else
  1111.         0;
  1112. #endif
  1113.  
  1114.     if (need_plt_entry && !s1->plt) {
  1115.         /* add PLT */
  1116.         s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
  1117.                               SHF_ALLOC | SHF_EXECINSTR);
  1118.         s1->plt->sh_entsize = 4;
  1119.     }
  1120.  
  1121.     /* If a got/plt entry already exists for that symbol, no need to add one */
  1122.     if (sym_index < s1->nb_sym_attrs) {
  1123.         if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
  1124.           return s1->sym_attrs[sym_index].plt_offset;
  1125.         else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset)
  1126.           return s1->sym_attrs[sym_index].got_offset;
  1127.     }
  1128.  
  1129.     symattr = alloc_sym_attr(s1, sym_index);
  1130.  
  1131.     /* Only store the GOT offset if it's not generated for the PLT entry.  */
  1132.     if (!need_plt_entry)
  1133.         symattr->got_offset = s1->got->data_offset;
  1134.  
  1135.     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
  1136.     name = (char *) symtab_section->link->data + sym->st_name;
  1137.     offset = sym->st_value;
  1138. #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
  1139.         if (need_plt_entry) {
  1140.             Section *plt;
  1141.             uint8_t *p;
  1142.             int modrm;
  1143.             unsigned long relofs;
  1144.  
  1145. #if defined(TCC_OUTPUT_DLL_WITH_PLT)
  1146.             modrm = 0x25;
  1147. #else
  1148.             /* if we build a DLL, we add a %ebx offset */
  1149.             if (s1->output_type == TCC_OUTPUT_DLL)
  1150.                 modrm = 0xa3;
  1151.             else
  1152.                 modrm = 0x25;
  1153. #endif
  1154.  
  1155.             /* add a PLT entry */
  1156.             plt = s1->plt;
  1157.             if (plt->data_offset == 0) {
  1158.                 /* first plt entry */
  1159.                 p = section_ptr_add(plt, 16);
  1160.                 p[0] = 0xff; /* pushl got + PTR_SIZE */
  1161.                 p[1] = modrm + 0x10;
  1162.                 write32le(p + 2, PTR_SIZE);
  1163.                 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
  1164.                 p[7] = modrm;
  1165.                 write32le(p + 8, PTR_SIZE * 2);
  1166.             }
  1167.  
  1168.             /* The PLT slot refers to the relocation entry it needs
  1169.                via offset.  The reloc entry is created below, so its
  1170.                offset is the current data_offset.  */
  1171.             relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
  1172.             symattr->plt_offset = plt->data_offset;
  1173.             p = section_ptr_add(plt, 16);
  1174.             p[0] = 0xff; /* jmp *(got + x) */
  1175.             p[1] = modrm;
  1176.             write32le(p + 2, s1->got->data_offset);
  1177.             p[6] = 0x68; /* push $xxx */
  1178. #ifdef TCC_TARGET_X86_64
  1179.             /* On x86-64, the relocation is referred to by _index_.  */
  1180.             write32le(p + 7, relofs / sizeof (ElfW_Rel));
  1181. #else
  1182.             write32le(p + 7, relofs);
  1183. #endif
  1184.             p[11] = 0xe9; /* jmp plt_start */
  1185.             write32le(p + 12, -(plt->data_offset));
  1186.  
  1187.             /* If this was an UNDEF symbol set the offset in the
  1188.                dynsymtab to the PLT slot, so that PC32 relocs to it
  1189.                can be resolved.  */
  1190.             if (sym->st_shndx == SHN_UNDEF)
  1191.                 offset = plt->data_offset - 16;
  1192.         }
  1193. #elif defined(TCC_TARGET_ARM)
  1194.         if (need_plt_entry) {
  1195.             Section *plt;
  1196.             uint8_t *p;
  1197.  
  1198.             /* if we build a DLL, we add a %ebx offset */
  1199.             if (s1->output_type == TCC_OUTPUT_DLL)
  1200.                 tcc_error("DLLs unimplemented!");
  1201.  
  1202.             /* add a PLT entry */
  1203.             plt = s1->plt;
  1204.             if (plt->data_offset == 0) {
  1205.                 /* first plt entry */
  1206.                 p = section_ptr_add(plt, 16);
  1207.                 write32le(p,    0xe52de004); /* push {lr}         */
  1208.                 write32le(p+4,  0xe59fe010); /* ldr lr, [pc, #16] */
  1209.                 write32le(p+8,  0xe08fe00e); /* add lr, pc, lr    */
  1210.                 write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
  1211.             }
  1212.  
  1213.             symattr->plt_offset = plt->data_offset;
  1214.             if (symattr->plt_thumb_stub) {
  1215.                 p = section_ptr_add(plt, 20);
  1216.                 write32le(p,   0x4778); /* bx pc */
  1217.                 write32le(p+2, 0x46c0); /* nop   */
  1218.                 p += 4;
  1219.             } else
  1220.                 p = section_ptr_add(plt, 16);
  1221.             write32le(p,   0xe59fc004); /* ldr ip, [pc, #4] ; GOT entry offset */
  1222.             write32le(p+4, 0xe08fc00c); /* add ip, pc, ip ; addr of GOT entry  */
  1223.             write32le(p+8, 0xe59cf000); /* ldr pc, [ip] ; jump to GOT entry */
  1224.             write32le(p+12, s1->got->data_offset); /* GOT entry off once patched */
  1225.  
  1226.             /* the symbol is modified so that it will be relocated to
  1227.                the PLT */
  1228.             if (sym->st_shndx == SHN_UNDEF)
  1229.                 offset = plt->data_offset - 16;
  1230.         }
  1231. #elif defined(TCC_TARGET_ARM64)
  1232.         if (need_plt_entry) {
  1233.             Section *plt;
  1234.             uint8_t *p;
  1235.  
  1236.             if (s1->output_type == TCC_OUTPUT_DLL)
  1237.                 tcc_error("DLLs unimplemented!");
  1238.  
  1239.             plt = s1->plt;
  1240.             if (plt->data_offset == 0)
  1241.                 section_ptr_add(plt, 32);
  1242.             symattr->plt_offset = plt->data_offset;
  1243.             p = section_ptr_add(plt, 16);
  1244.             write32le(p, s1->got->data_offset);
  1245.             write32le(p + 4, (uint64_t)s1->got->data_offset >> 32);
  1246.  
  1247.             if (sym->st_shndx == SHN_UNDEF)
  1248.                 offset = plt->data_offset - 16;
  1249.         }
  1250. #elif defined(TCC_TARGET_C67)
  1251.     if (s1->dynsym) {
  1252.         tcc_error("C67 got not implemented");
  1253.     }
  1254. #else
  1255. #error unsupported CPU
  1256. #endif
  1257.     if (s1->dynsym) {
  1258.         /* XXX This might generate multiple syms for name.  */
  1259.         index = put_elf_sym(s1->dynsym, offset,
  1260.                             size, info, 0, sym->st_shndx, name);
  1261.         /* Create the relocation (it's against the GOT for PLT
  1262.            and GOT relocs).  */
  1263.         put_elf_reloc(s1->dynsym, s1->got,
  1264.                       s1->got->data_offset,
  1265.                       reloc_type, index);
  1266.     } else {
  1267.         /* Without .dynsym (i.e. static link or memory output) we
  1268.            still need relocs against the generated got, so as to fill
  1269.            the entries with the symbol values (determined later).  */
  1270.         put_elf_reloc(symtab_section, s1->got,
  1271.                       s1->got->data_offset,
  1272.                       reloc_type, sym_index);
  1273.     }
  1274.     /* And now create the GOT slot itself.  */
  1275.     ptr = section_ptr_add(s1->got, PTR_SIZE);
  1276.     *ptr = 0;
  1277.     if (need_plt_entry)
  1278.       return symattr->plt_offset;
  1279.     else
  1280.       return symattr->got_offset;
  1281. }
  1282.  
  1283. /* build GOT and PLT entries */
  1284. ST_FUNC void build_got_entries(TCCState *s1)
  1285. {
  1286.     Section *s;
  1287.     ElfW_Rel *rel;
  1288.     ElfW(Sym) *sym;
  1289.     int i, type, reloc_type, sym_index;
  1290.  
  1291.     for(i = 1; i < s1->nb_sections; i++) {
  1292.         s = s1->sections[i];
  1293.         if (s->sh_type != SHT_RELX)
  1294.             continue;
  1295.         /* no need to handle got relocations */
  1296.         if (s->link != symtab_section)
  1297.             continue;
  1298.         for_each_elem(s, 0, rel, ElfW_Rel) {
  1299.             type = ELFW(R_TYPE)(rel->r_info);
  1300.             switch(type) {
  1301. #if defined(TCC_TARGET_I386)
  1302.             case R_386_GOT32:
  1303.             case R_386_GOT32X:
  1304.             case R_386_GOTOFF:
  1305.             case R_386_GOTPC:
  1306.             case R_386_PLT32:
  1307.                 if (!s1->got)
  1308.                     build_got(s1);
  1309.                 if (type == R_386_GOT32 || type == R_386_GOT32X ||
  1310.                     type == R_386_PLT32) {
  1311.                     sym_index = ELFW(R_SYM)(rel->r_info);
  1312.                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
  1313.                     /* look at the symbol got offset. If none, then add one */
  1314.                     if (type == R_386_GOT32 || type == R_386_GOT32X)
  1315.                         reloc_type = R_386_GLOB_DAT;
  1316.                     else
  1317.                         reloc_type = R_386_JMP_SLOT;
  1318.                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
  1319.                                   sym_index);
  1320.                 }
  1321.                 break;
  1322. #elif defined(TCC_TARGET_ARM)
  1323.             case R_ARM_PC24:
  1324.             case R_ARM_CALL:
  1325.             case R_ARM_JUMP24:
  1326.             case R_ARM_GOT32:
  1327.             case R_ARM_GOTOFF:
  1328.             case R_ARM_GOTPC:
  1329.             case R_ARM_PLT32:
  1330.                 if (!s1->got)
  1331.                     build_got(s1);
  1332.                 sym_index = ELFW(R_SYM)(rel->r_info);
  1333.                 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
  1334.                 if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC
  1335.                     && sym->st_shndx == SHN_UNDEF) {
  1336.                     unsigned long ofs;
  1337.                     /* look at the symbol got offset. If none, then add one */
  1338.                     if (type == R_ARM_GOT32)
  1339.                         reloc_type = R_ARM_GLOB_DAT;
  1340.                     else
  1341.                         reloc_type = R_ARM_JUMP_SLOT;
  1342.                     ofs = put_got_entry(s1, reloc_type, sym->st_size,
  1343.                                         sym->st_info, sym_index);
  1344. #ifdef DEBUG_RELOC
  1345.                     printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
  1346.                             (char *) symtab_section->link->data + sym->st_name,
  1347.                             type, sym->st_shndx, ofs);
  1348. #endif
  1349.                     if (type != R_ARM_GOT32) {
  1350.                         addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
  1351.                                                 + rel->r_offset);
  1352.                         /* x must be signed!  */
  1353.                         int x = *ptr & 0xffffff;
  1354.                         x = (x << 8) >> 8;
  1355.                         x <<= 2;
  1356.                         x += ofs;
  1357.                         x >>= 2;
  1358. #ifdef DEBUG_RELOC
  1359.                         printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
  1360.                                 (*ptr & 0xff000000) | x, x);
  1361. #endif
  1362.                         *ptr = (*ptr & 0xff000000) | x;
  1363.                     }
  1364.                 }
  1365.                 break;
  1366.             case R_ARM_THM_JUMP24:
  1367.                 sym_index = ELFW(R_SYM)(rel->r_info);
  1368.                 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
  1369.                 /* We are relocating a jump from thumb code to arm code */
  1370.                 if (sym->st_shndx != SHN_UNDEF && !(sym->st_value & 1)) {
  1371.                     int index;
  1372.                     uint8_t *p;
  1373.                     char *name, buf[1024];
  1374.                     Section *text_section;
  1375.  
  1376.                     name = (char *) symtab_section->link->data + sym->st_name;
  1377.                     text_section = s1->sections[sym->st_shndx];
  1378.                     /* Modify reloc to target a thumb stub to switch to ARM */
  1379.                     snprintf(buf, sizeof(buf), "%s_from_thumb", name);
  1380.                     index = put_elf_sym(symtab_section,
  1381.                                         text_section->data_offset + 1,
  1382.                                         sym->st_size, sym->st_info, 0,
  1383.                                         sym->st_shndx, buf);
  1384.                     rel->r_info = ELFW(R_INFO)(index, type);
  1385.                     /* Create a thumb stub fonction to switch to ARM mode */
  1386.                     put_elf_reloc(symtab_section, text_section,
  1387.                                   text_section->data_offset + 4, R_ARM_JUMP24,
  1388.                                   sym_index);
  1389.                     p = section_ptr_add(text_section, 8);
  1390.                     write32le(p,   0x4778); /* bx pc */
  1391.                     write32le(p+2, 0x46c0); /* nop   */
  1392.                     write32le(p+4, 0xeafffffe); /* b $sym */
  1393.                 }
  1394. #elif defined(TCC_TARGET_ARM64)
  1395.                 //xx Other cases may be required here:
  1396.             case R_AARCH64_ADR_GOT_PAGE:
  1397.             case R_AARCH64_LD64_GOT_LO12_NC:
  1398.                 if (!s1->got)
  1399.                     build_got(s1);
  1400.                 sym_index = ELFW(R_SYM)(rel->r_info);
  1401.                 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
  1402.                 reloc_type = R_AARCH64_GLOB_DAT;
  1403.                 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
  1404.                               sym_index);
  1405.                 break;
  1406.  
  1407.             case R_AARCH64_JUMP26:
  1408.             case R_AARCH64_CALL26:
  1409.                 if (!s1->got)
  1410.                     build_got(s1);
  1411.                 sym_index = ELFW(R_SYM)(rel->r_info);
  1412.                 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
  1413.                 if (sym->st_shndx == SHN_UNDEF) {
  1414.                     unsigned long ofs;
  1415.                     reloc_type = R_AARCH64_JUMP_SLOT;
  1416.                     ofs = put_got_entry(s1, reloc_type, sym->st_size,
  1417.                                         sym->st_info, sym_index);
  1418.                     /* We store the place of the generated PLT slot
  1419.                        in our addend.  */
  1420.                     rel->r_addend += ofs;
  1421.                 }
  1422.                 break;
  1423. #elif defined(TCC_TARGET_C67)
  1424.             case R_C60_GOT32:
  1425.             case R_C60_GOTOFF:
  1426.             case R_C60_GOTPC:
  1427.             case R_C60_PLT32:
  1428.                 if (!s1->got)
  1429.                     build_got(s1);
  1430.                 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
  1431.                     sym_index = ELFW(R_SYM)(rel->r_info);
  1432.                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
  1433.                     /* look at the symbol got offset. If none, then add one */
  1434.                     if (type == R_C60_GOT32)
  1435.                         reloc_type = R_C60_GLOB_DAT;
  1436.                     else
  1437.                         reloc_type = R_C60_JMP_SLOT;
  1438.                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
  1439.                                   sym_index);
  1440.                 }
  1441.                 break;
  1442. #elif defined(TCC_TARGET_X86_64)
  1443.             case R_X86_64_GOT32:
  1444.             case R_X86_64_GOTTPOFF:
  1445.             case R_X86_64_GOTPCREL:
  1446.             case R_X86_64_GOTPCRELX:
  1447.             case R_X86_64_REX_GOTPCRELX:
  1448.             case R_X86_64_PLT32:
  1449.                 sym_index = ELFW(R_SYM)(rel->r_info);
  1450.                 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
  1451.                 if (type == R_X86_64_PLT32 &&
  1452.                     ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT)
  1453.                   {
  1454.                     rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
  1455.                     break;
  1456.                   }
  1457.  
  1458.                 if (!s1->got) {
  1459.                     build_got(s1);
  1460.                     sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
  1461.                 }
  1462.                 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
  1463.                     type == R_X86_64_GOTPCRELX ||
  1464.                     type == R_X86_64_REX_GOTPCRELX ||
  1465.                     type == R_X86_64_PLT32) {
  1466.                     unsigned long ofs;
  1467.                     /* look at the symbol got offset. If none, then add one */
  1468.                     if (type == R_X86_64_PLT32)
  1469.                         reloc_type = R_X86_64_JUMP_SLOT;
  1470.                     else
  1471.                         reloc_type = R_X86_64_GLOB_DAT;
  1472.                     ofs = put_got_entry(s1, reloc_type, sym->st_size,
  1473.                                         sym->st_info, sym_index);
  1474.                     if (type == R_X86_64_PLT32)
  1475.                         /* We store the place of the generated PLT slot
  1476.                            in our addend.  */
  1477.                         rel->r_addend += ofs;
  1478.                 }
  1479.                 break;
  1480. #else
  1481. #error unsupported CPU
  1482. #endif
  1483.             default:
  1484.                 break;
  1485.             }
  1486.         }
  1487.     }
  1488. }
  1489.  
  1490. ST_FUNC Section *new_symtab(TCCState *s1,
  1491.                            const char *symtab_name, int sh_type, int sh_flags,
  1492.                            const char *strtab_name,
  1493.                            const char *hash_name, int hash_sh_flags)
  1494. {
  1495.     Section *symtab, *strtab, *hash;
  1496.     int *ptr, nb_buckets;
  1497.  
  1498.     symtab = new_section(s1, symtab_name, sh_type, sh_flags);
  1499.     symtab->sh_entsize = sizeof(ElfW(Sym));
  1500.     strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
  1501.     put_elf_str(strtab, "");
  1502.     symtab->link = strtab;
  1503.     put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
  1504.  
  1505.     nb_buckets = 1;
  1506.  
  1507.     hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
  1508.     hash->sh_entsize = sizeof(int);
  1509.     symtab->hash = hash;
  1510.     hash->link = symtab;
  1511.  
  1512.     ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
  1513.     ptr[0] = nb_buckets;
  1514.     ptr[1] = 1;
  1515.     memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
  1516.     return symtab;
  1517. }
  1518.  
  1519. /* put dynamic tag */
  1520. static void put_dt(Section *dynamic, int dt, addr_t val)
  1521. {
  1522.     ElfW(Dyn) *dyn;
  1523.     dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
  1524.     dyn->d_tag = dt;
  1525.     dyn->d_un.d_val = val;
  1526. }
  1527.  
  1528. static void add_init_array_defines(TCCState *s1, const char *section_name)
  1529. {
  1530.     Section *s;
  1531.     long end_offset;
  1532.     char sym_start[1024];
  1533.     char sym_end[1024];
  1534.  
  1535.     snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
  1536.     snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
  1537.  
  1538.     s = find_section(s1, section_name);
  1539.     if (!s) {
  1540.         end_offset = 0;
  1541.         s = data_section;
  1542.     } else {
  1543.         end_offset = s->data_offset;
  1544.     }
  1545.  
  1546.     add_elf_sym(symtab_section,
  1547.                 0, 0,
  1548.                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
  1549.                 s->sh_num, sym_start);
  1550.     add_elf_sym(symtab_section,
  1551.                 end_offset, 0,
  1552.                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
  1553.                 s->sh_num, sym_end);
  1554. }
  1555.  
  1556. static int tcc_add_support(TCCState *s1, const char *filename)
  1557. {
  1558.     char buf[1024];
  1559.     snprintf(buf, sizeof(buf), "%s/%s/%s", s1->tcc_lib_path,
  1560.     /* an cpu specific path inside tcc_lib_path, mainly for keeping libtcc1.a */
  1561.     #ifdef TCC_TARGET_I386
  1562.         "i386"
  1563.     #endif
  1564.     #ifdef TCC_TARGET_X86_64
  1565.         "x86-64"
  1566.     #endif
  1567.     #ifdef TCC_TARGET_ARM
  1568.         "arm"
  1569.     #endif
  1570.     #ifdef TCC_TARGET_ARM64
  1571.         "arm64"
  1572.     #endif
  1573.     #ifdef TCC_TARGET_C67
  1574.         "C67"
  1575.     #endif
  1576.         ,filename);
  1577.  
  1578.     return tcc_add_file(s1, buf, TCC_FILETYPE_BINARY);
  1579. }
  1580.  
  1581. ST_FUNC void tcc_add_bcheck(TCCState *s1)
  1582. {
  1583. #ifdef CONFIG_TCC_BCHECK
  1584.     addr_t *ptr;
  1585.  
  1586.     if (0 == s1->do_bounds_check)
  1587.         return;
  1588.  
  1589.     /* XXX: add an object file to do that */
  1590.     ptr = section_ptr_add(bounds_section, sizeof(*ptr));
  1591.     *ptr = 0;
  1592.     add_elf_sym(symtab_section, 0, 0,
  1593.                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
  1594.                 bounds_section->sh_num, "__bounds_start");
  1595.     if (s1->output_type != TCC_OUTPUT_MEMORY) {
  1596.         /* add 'call __bound_init()' in .init section */
  1597.  
  1598.         /* XXX not called on MSYS, reason is unknown. For this
  1599.            case a call to __bound_init is performed in bcheck.c
  1600.            when __bound_ptr_add, __bound_new_region,
  1601.            __bound_delete_region called */
  1602.  
  1603.         int sym_index = find_elf_sym(symtab_section, "__bound_init");
  1604.         if (sym_index) {
  1605.             Section *init_section = find_section(s1, ".init");
  1606.             unsigned char *pinit = section_ptr_add(init_section, 5);
  1607.             pinit[0] = 0xe8;
  1608.             write32le(pinit + 1, -4);
  1609.             put_elf_reloc(symtab_section, init_section,
  1610.                       init_section->data_offset - 4, R_386_PC32, sym_index);
  1611.         }
  1612.         else
  1613.             tcc_warning("__bound_init not defined");
  1614.     }
  1615. #endif
  1616. }
  1617.  
  1618. /* add tcc runtime libraries */
  1619. ST_FUNC void tcc_add_runtime(TCCState *s1)
  1620. {
  1621.     tcc_add_pragma_libs(s1);
  1622.     /* add libc */
  1623.     if (!s1->nostdlib) {
  1624. #if !defined (TCC_TARGET_MEOS)
  1625.         tcc_add_library(s1, "c");
  1626.     #ifdef CONFIG_USE_LIBGCC
  1627.         if (!s1->static_link) {
  1628.             tcc_add_file(s1, TCC_LIBGCC, TCC_FILETYPE_BINARY);
  1629.         }
  1630.     #endif
  1631.         tcc_add_support(s1, "libtcc1.a");
  1632. #else
  1633.         if (tcc_add_library_err(s1, "c") < 0 ||
  1634.             tcc_add_library_err(s1, "tcc1") < 0) {
  1635.             exit(1);
  1636.         }
  1637. #endif
  1638.     }
  1639.  
  1640.     /* tcc_add_bcheck tries to relocate a call to __bound_init in _init so
  1641.        libtcc1.a must be loaded before for __bound_init to be defined and
  1642.        crtn.o must be loaded after to not finalize _init too early. */
  1643.     tcc_add_bcheck(s1);
  1644. #if !defined (TCC_TARGET_MEOS)
  1645.     if (!s1->nostdlib) {
  1646.         /* add crt end if not memory output */
  1647.         if (s1->output_type != TCC_OUTPUT_MEMORY)
  1648.             tcc_add_crt(s1, "crtn.o");
  1649.     }
  1650. #endif
  1651. }
  1652.  
  1653. /* add various standard linker symbols (must be done after the
  1654.    sections are filled (for example after allocating common
  1655.    symbols)) */
  1656. ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
  1657. {
  1658.     char buf[1024];
  1659.     int i;
  1660.     Section *s;
  1661.  
  1662.     add_elf_sym(symtab_section,
  1663.                 text_section->data_offset, 0,
  1664.                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
  1665.                 text_section->sh_num, "_etext");
  1666.     add_elf_sym(symtab_section,
  1667.                 data_section->data_offset, 0,
  1668.                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
  1669.                 data_section->sh_num, "_edata");
  1670.     add_elf_sym(symtab_section,
  1671.                 bss_section->data_offset, 0,
  1672.                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
  1673.                 bss_section->sh_num, "_end");
  1674.     /* horrible new standard ldscript defines */
  1675.     add_init_array_defines(s1, ".preinit_array");
  1676.     add_init_array_defines(s1, ".init_array");
  1677.     add_init_array_defines(s1, ".fini_array");
  1678.  
  1679.     /* add start and stop symbols for sections whose name can be
  1680.        expressed in C */
  1681.     for(i = 1; i < s1->nb_sections; i++) {
  1682.         s = s1->sections[i];
  1683.         if (s->sh_type == SHT_PROGBITS &&
  1684.             (s->sh_flags & SHF_ALLOC)) {
  1685.             const char *p;
  1686.             int ch;
  1687.  
  1688.             /* check if section name can be expressed in C */
  1689.             p = s->name;
  1690.             for(;;) {
  1691.                 ch = *p;
  1692.                 if (!ch)
  1693.                     break;
  1694.                 if (!isid(ch) && !isnum(ch))
  1695.                     goto next_sec;
  1696.                 p++;
  1697.             }
  1698.             snprintf(buf, sizeof(buf), "__start_%s", s->name);
  1699.             add_elf_sym(symtab_section,
  1700.                         0, 0,
  1701.                         ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
  1702.                         s->sh_num, buf);
  1703.             snprintf(buf, sizeof(buf), "__stop_%s", s->name);
  1704.             add_elf_sym(symtab_section,
  1705.                         s->data_offset, 0,
  1706.                         ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
  1707.                         s->sh_num, buf);
  1708.         }
  1709.     next_sec: ;
  1710.     }
  1711. }
  1712.  
  1713. static void tcc_output_binary(TCCState *s1, FILE *f,
  1714.                               const int *sec_order)
  1715. {
  1716.     Section *s;
  1717.     int i, offset, size;
  1718.  
  1719.     offset = 0;
  1720.     for(i=1;i<s1->nb_sections;i++) {
  1721.         s = s1->sections[sec_order[i]];
  1722.         if (s->sh_type != SHT_NOBITS &&
  1723.             (s->sh_flags & SHF_ALLOC)) {
  1724.             while (offset < s->sh_offset) {
  1725.                 fputc(0, f);
  1726.                 offset++;
  1727.             }
  1728.             size = s->sh_size;
  1729.             fwrite(s->data, 1, size, f);
  1730.             offset += size;
  1731.         }
  1732.     }
  1733. }
  1734.  
  1735. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  1736. #define HAVE_PHDR       1
  1737. #define EXTRA_RELITEMS  14
  1738.  
  1739. /* move the relocation value from .dynsym to .got */
  1740. void patch_dynsym_undef(TCCState *s1, Section *s)
  1741. {
  1742.     uint32_t *gotd = (void *)s1->got->data;
  1743.     ElfW(Sym) *sym;
  1744.  
  1745.     gotd += 3; /* dummy entries in .got */
  1746.     /* relocate symbols in .dynsym */
  1747.     for_each_elem(s, 1, sym, ElfW(Sym)) {
  1748.         if (sym->st_shndx == SHN_UNDEF) {
  1749.             *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
  1750.             sym->st_value = 0;
  1751.         }
  1752.     }
  1753. }
  1754. #else
  1755. #define HAVE_PHDR      1
  1756. #define EXTRA_RELITEMS 9
  1757.  
  1758. /* zero plt offsets of weak symbols in .dynsym */
  1759. void patch_dynsym_undef(TCCState *s1, Section *s)
  1760. {
  1761.     ElfW(Sym) *sym;
  1762.  
  1763.     for_each_elem(s, 1, sym, ElfW(Sym))
  1764.         if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
  1765.             sym->st_value = 0;
  1766. }
  1767. #endif
  1768.  
  1769. ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
  1770. {
  1771.     int sym_index = ELFW(R_SYM) (rel->r_info);
  1772.     ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
  1773.     unsigned long offset;
  1774.  
  1775.     if (sym_index >= s1->nb_sym_attrs)
  1776.         return;
  1777.     offset = s1->sym_attrs[sym_index].got_offset;
  1778.     section_reserve(s1->got, offset + PTR_SIZE);
  1779. #ifdef TCC_TARGET_X86_64
  1780.     /* only works for x86-64 */
  1781.     write32le(s1->got->data + offset + 4, sym->st_value >> 32);
  1782. #endif
  1783.     write32le(s1->got->data + offset, sym->st_value & 0xffffffff);
  1784. }
  1785.  
  1786. /* Perform relocation to GOT or PLT entries */
  1787. ST_FUNC void fill_got(TCCState *s1)
  1788. {
  1789.     Section *s;
  1790.     ElfW_Rel *rel;
  1791.     int i;
  1792.  
  1793.     for(i = 1; i < s1->nb_sections; i++) {
  1794.         s = s1->sections[i];
  1795.         if (s->sh_type != SHT_RELX)
  1796.             continue;
  1797.         /* no need to handle got relocations */
  1798.         if (s->link != symtab_section)
  1799.             continue;
  1800.         for_each_elem(s, 0, rel, ElfW_Rel) {
  1801.             switch (ELFW(R_TYPE) (rel->r_info)) {
  1802.                 case R_X86_64_GOT32:
  1803.                 case R_X86_64_GOTPCREL:
  1804.                 case R_X86_64_GOTPCRELX:
  1805.                 case R_X86_64_REX_GOTPCRELX:
  1806.                 case R_X86_64_PLT32:
  1807.                     fill_got_entry(s1, rel);
  1808.                     break;
  1809.             }
  1810.         }
  1811.     }
  1812. }
  1813.  
  1814. /* Bind symbols of executable: resolve undefined symbols from exported symbols
  1815.    in shared libraries and export non local defined symbols to shared libraries
  1816.    if -rdynamic switch was given on command line */
  1817. static void bind_exe_dynsyms(TCCState *s1)
  1818. {
  1819.     const char *name;
  1820.     int sym_index, index;
  1821.     ElfW(Sym) *sym, *esym;
  1822.     int type;
  1823.  
  1824.     /* Resolve undefined symbols from dynamic symbols. When there is a match:
  1825.        - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
  1826.        - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
  1827.     for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
  1828.         if (sym->st_shndx == SHN_UNDEF) {
  1829.             name = (char *) symtab_section->link->data + sym->st_name;
  1830.             sym_index = find_elf_sym(s1->dynsymtab_section, name);
  1831.             if (sym_index) {
  1832.                 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
  1833.                 type = ELFW(ST_TYPE)(esym->st_info);
  1834.                 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
  1835.                     /* Indirect functions shall have STT_FUNC type in executable
  1836.                      * dynsym section. Indeed, a dlsym call following a lazy
  1837.                      * resolution would pick the symbol value from the
  1838.                      * executable dynsym entry which would contain the address
  1839.                      * of the function wanted by the caller of dlsym instead of
  1840.                      * the address of the function that would return that
  1841.                      * address */
  1842.                     put_got_entry(s1, R_JMP_SLOT, esym->st_size,
  1843.                                   ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
  1844.                                   sym - (ElfW(Sym) *)symtab_section->data);
  1845.                 } else if (type == STT_OBJECT) {
  1846.                     unsigned long offset;
  1847.                     ElfW(Sym) *dynsym;
  1848.                     offset = bss_section->data_offset;
  1849.                     /* XXX: which alignment ? */
  1850.                     offset = (offset + 16 - 1) & -16;
  1851.                     index = put_elf_sym(s1->dynsym, offset, esym->st_size,
  1852.                                         esym->st_info, 0, bss_section->sh_num,
  1853.                                         name);
  1854.                     /* Ensure R_COPY works for weak symbol aliases */
  1855.                     if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
  1856.                         for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
  1857.                             if ((dynsym->st_value == esym->st_value)
  1858.                                 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
  1859.                                 char *dynname = (char *) s1->dynsymtab_section->link->data
  1860.                                                 + dynsym->st_name;
  1861.                                 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
  1862.                                             dynsym->st_info, 0,
  1863.                                             bss_section->sh_num, dynname);
  1864.                                 break;
  1865.                             }
  1866.                         }
  1867.                     }
  1868.                     put_elf_reloc(s1->dynsym, bss_section,
  1869.                                   offset, R_COPY, index);
  1870.                     offset += esym->st_size;
  1871.                     bss_section->data_offset = offset;
  1872.                 }
  1873.             } else {
  1874.                 /* STB_WEAK undefined symbols are accepted */
  1875.                 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
  1876.                 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
  1877.                     !strcmp(name, "_fp_hw")) {
  1878.                 } else {
  1879.                     tcc_error_noabort("undefined symbol '%s'", name);
  1880.                 }
  1881.             }
  1882.         } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
  1883.             /* if -rdynamic option, then export all non local symbols */
  1884.             name = (char *) symtab_section->link->data + sym->st_name;
  1885.             put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
  1886.                         0, sym->st_shndx, name);
  1887.         }
  1888.     }
  1889. }
  1890.  
  1891. /* Bind symbols of libraries: export non local symbols of executable that
  1892.    resolve undefined symbols of shared libraries */
  1893. static void bind_libs_dynsyms(TCCState *s1)
  1894. {
  1895.     const char *name;
  1896.     int sym_index;
  1897.     ElfW(Sym) *sym, *esym;
  1898.  
  1899.     /* now look at unresolved dynamic symbols and export
  1900.        corresponding symbol */
  1901.     for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
  1902.         name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
  1903.         sym_index = find_elf_sym(symtab_section, name);
  1904.         if (sym_index) {
  1905.             /* XXX: avoid adding a symbol if already present because of
  1906.                -rdynamic ? */
  1907.             sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
  1908.             if (sym->st_shndx != SHN_UNDEF)
  1909.                 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
  1910.                             sym->st_info, 0, sym->st_shndx, name);
  1911.         } else if (esym->st_shndx == SHN_UNDEF) {
  1912.             /* weak symbols can stay undefined */
  1913.             if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
  1914.                 tcc_warning("undefined dynamic symbol '%s'", name);
  1915.         }
  1916.     }
  1917. }
  1918.  
  1919. /* Export all non local symbols (for shared libraries) */
  1920. static void export_global_syms(TCCState *s1)
  1921. {
  1922.     int nb_syms, dynindex, index;
  1923.     const char *name;
  1924.     ElfW(Sym) *sym;
  1925.  
  1926.     nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
  1927.     s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
  1928.     for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
  1929.         if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
  1930.             name = (char *) symtab_section->link->data + sym->st_name;
  1931.             dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
  1932.                                    sym->st_info, 0, sym->st_shndx, name);
  1933.             index = sym - (ElfW(Sym) *) symtab_section->data;
  1934.             s1->symtab_to_dynsym[index] = dynindex;
  1935.         }
  1936.     }
  1937. }
  1938.  
  1939. /* relocate the PLT: compute addresses and offsets in the PLT now that final
  1940.    address for PLT and GOT are known (see fill_program_header) */
  1941. ST_FUNC void relocate_plt(TCCState *s1)
  1942. {
  1943.     uint8_t *p, *p_end;
  1944.  
  1945.     if (!s1->plt)
  1946.       return;
  1947.  
  1948.     p = s1->plt->data;
  1949.     p_end = p + s1->plt->data_offset;
  1950.     if (p < p_end) {
  1951. #if defined(TCC_TARGET_I386)
  1952.         write32le(p + 2, read32le(p + 2) + s1->got->sh_addr);
  1953.         write32le(p + 8, read32le(p + 8) + s1->got->sh_addr);
  1954.         p += 16;
  1955.         while (p < p_end) {
  1956.             write32le(p + 2, read32le(p + 2) + s1->got->sh_addr);
  1957.             p += 16;
  1958.         }
  1959. #elif defined(TCC_TARGET_X86_64)
  1960.         int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
  1961.         write32le(p + 2, read32le(p + 2) + x);
  1962.         write32le(p + 8, read32le(p + 8) + x - 6);
  1963.         p += 16;
  1964.         while (p < p_end) {
  1965.             write32le(p + 2, read32le(p + 2) + x + s1->plt->data - p);
  1966.             p += 16;
  1967.         }
  1968. #elif defined(TCC_TARGET_ARM)
  1969.         int x;
  1970.         x=s1->got->sh_addr - s1->plt->sh_addr - 12;
  1971.         p += 16;
  1972.         while (p < p_end) {
  1973.             if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
  1974.                 p += 4;
  1975.             write32le(p + 12, x + read32le(p + 12) + s1->plt->data - p);
  1976.             p += 16;
  1977.         }
  1978. #elif defined(TCC_TARGET_ARM64)
  1979.         uint64_t plt = s1->plt->sh_addr;
  1980.         uint64_t got = s1->got->sh_addr;
  1981.         uint64_t off = (got >> 12) - (plt >> 12);
  1982.         if ((off + ((uint32_t)1 << 20)) >> 21)
  1983.             tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
  1984.         write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
  1985.         write32le(p + 4, (0x90000010 | // adrp x16,...
  1986.                           (off & 0x1ffffc) << 3 | (off & 3) << 29));
  1987.         write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
  1988.                           (got & 0xff8) << 7));
  1989.         write32le(p + 12, (0x91000210 | // add x16,x16,#...
  1990.                            (got & 0xfff) << 10));
  1991.         write32le(p + 16, 0xd61f0220); // br x17
  1992.         write32le(p + 20, 0xd503201f); // nop
  1993.         write32le(p + 24, 0xd503201f); // nop
  1994.         write32le(p + 28, 0xd503201f); // nop
  1995.         p += 32;
  1996.         while (p < p_end) {
  1997.             uint64_t pc = plt + (p - s1->plt->data);
  1998.             uint64_t addr = got + read64le(p);
  1999.             uint64_t off = (addr >> 12) - (pc >> 12);
  2000.             if ((off + ((uint32_t)1 << 20)) >> 21)
  2001.                 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
  2002.             write32le(p, (0x90000010 | // adrp x16,...
  2003.                           (off & 0x1ffffc) << 3 | (off & 3) << 29));
  2004.             write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
  2005.                               (addr & 0xff8) << 7));
  2006.             write32le(p + 8, (0x91000210 | // add x16,x16,#...
  2007.                               (addr & 0xfff) << 10));
  2008.             write32le(p + 12, 0xd61f0220); // br x17
  2009.             p += 16;
  2010.         }
  2011. #elif defined(TCC_TARGET_C67)
  2012.         /* XXX: TODO */
  2013. #else
  2014. #error unsupported CPU
  2015. #endif
  2016.     }
  2017. }
  2018.  
  2019. /* Allocate strings for section names and decide if an unallocated section
  2020.    should be output.
  2021.  
  2022.    NOTE: the strsec section comes last, so its size is also correct ! */
  2023. static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
  2024. {
  2025.     int i;
  2026.     Section *s;
  2027.  
  2028.     /* Allocate strings for section names */
  2029.     for(i = 1; i < s1->nb_sections; i++) {
  2030.         s = s1->sections[i];
  2031.         s->sh_name = put_elf_str(strsec, s->name);
  2032.         /* when generating a DLL, we include relocations but we may
  2033.            patch them */
  2034.         if (file_type == TCC_OUTPUT_DLL &&
  2035.             s->sh_type == SHT_RELX &&
  2036.             !(s->sh_flags & SHF_ALLOC)) {
  2037.             /* gr: avoid bogus relocs for empty (debug) sections */
  2038.             if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
  2039.                 prepare_dynamic_rel(s1, s);
  2040.             else if (s1->do_debug)
  2041.                 s->sh_size = s->data_offset;
  2042.         } else if (s1->do_debug ||
  2043.             file_type == TCC_OUTPUT_OBJ ||
  2044.             file_type == TCC_OUTPUT_EXE ||
  2045.             (s->sh_flags & SHF_ALLOC) ||
  2046.             i == (s1->nb_sections - 1)) {
  2047.             /* we output all sections if debug or object file */
  2048.             s->sh_size = s->data_offset;
  2049.         }
  2050.     }
  2051. }
  2052.  
  2053. /* Info to be copied in dynamic section */
  2054. struct dyn_inf {
  2055.     Section *dynamic;
  2056.     Section *dynstr;
  2057.     unsigned long dyn_rel_off;
  2058.     addr_t rel_addr;
  2059.     addr_t rel_size;
  2060. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  2061.     addr_t bss_addr;
  2062.     addr_t bss_size;
  2063. #endif
  2064. };
  2065.  
  2066. /* Assign sections to segments and decide how are sections laid out when loaded
  2067.    in memory. This function also fills corresponding program headers. */
  2068. static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
  2069.                            Section *interp, Section* strsec,
  2070.                            struct dyn_inf *dyninf, int *sec_order)
  2071. {
  2072.     int i, j, k, file_type, sh_order_index, file_offset;
  2073.     unsigned long s_align;
  2074.     long long tmp;
  2075.     addr_t addr;
  2076.     ElfW(Phdr) *ph;
  2077.     Section *s;
  2078.  
  2079.     file_type = s1->output_type;
  2080.     sh_order_index = 1;
  2081.     file_offset = 0;
  2082.     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
  2083.         file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
  2084.     s_align = ELF_PAGE_SIZE;
  2085.     if (s1->section_align)
  2086.         s_align = s1->section_align;
  2087.  
  2088.     if (phnum > 0) {
  2089.         if (s1->has_text_addr) {
  2090.             int a_offset, p_offset;
  2091.             addr = s1->text_addr;
  2092.             /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
  2093.                ELF_PAGE_SIZE */
  2094.             a_offset = (int) (addr & (s_align - 1));
  2095.             p_offset = file_offset & (s_align - 1);
  2096.             if (a_offset < p_offset)
  2097.                 a_offset += s_align;
  2098.             file_offset += (a_offset - p_offset);
  2099.         } else {
  2100.             if (file_type == TCC_OUTPUT_DLL)
  2101.                 addr = 0;
  2102.             else
  2103.                 addr = ELF_START_ADDR;
  2104.             /* compute address after headers */
  2105.             addr += (file_offset & (s_align - 1));
  2106.         }
  2107.  
  2108.         ph = &phdr[0];
  2109.         /* Leave one program headers for the program interpreter and one for
  2110.            the program header table itself if needed. These are done later as
  2111.            they require section layout to be done first. */
  2112.         if (interp)
  2113.             ph += 1 + HAVE_PHDR;
  2114.  
  2115.         /* dynamic relocation table information, for .dynamic section */
  2116.         dyninf->rel_addr = dyninf->rel_size = 0;
  2117. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  2118.         dyninf->bss_addr = dyninf->bss_size = 0;
  2119. #endif
  2120.  
  2121.         for(j = 0; j < 2; j++) {
  2122.             ph->p_type = PT_LOAD;
  2123.             if (j == 0)
  2124.                 ph->p_flags = PF_R | PF_X;
  2125.             else
  2126.                 ph->p_flags = PF_R | PF_W;
  2127.             ph->p_align = s_align;
  2128.  
  2129.             /* Decide the layout of sections loaded in memory. This must
  2130.                be done before program headers are filled since they contain
  2131.                info about the layout. We do the following ordering: interp,
  2132.                symbol tables, relocations, progbits, nobits */
  2133.             /* XXX: do faster and simpler sorting */
  2134.             for(k = 0; k < 5; k++) {
  2135.                 for(i = 1; i < s1->nb_sections; i++) {
  2136.                     s = s1->sections[i];
  2137.                     /* compute if section should be included */
  2138.                     if (j == 0) {
  2139.                         if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
  2140.                             SHF_ALLOC)
  2141.                             continue;
  2142.                     } else {
  2143.                         if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
  2144.                             (SHF_ALLOC | SHF_WRITE))
  2145.                             continue;
  2146.                     }
  2147.                     if (s == interp) {
  2148.                         if (k != 0)
  2149.                             continue;
  2150.                     } else if (s->sh_type == SHT_DYNSYM ||
  2151.                                s->sh_type == SHT_STRTAB ||
  2152.                                s->sh_type == SHT_HASH) {
  2153.                         if (k != 1)
  2154.                             continue;
  2155.                     } else if (s->sh_type == SHT_RELX) {
  2156.                         if (k != 2)
  2157.                             continue;
  2158.                     } else if (s->sh_type == SHT_NOBITS) {
  2159.                         if (k != 4)
  2160.                             continue;
  2161.                     } else {
  2162.                         if (k != 3)
  2163.                             continue;
  2164.                     }
  2165.                     sec_order[sh_order_index++] = i;
  2166.  
  2167.                     /* section matches: we align it and add its size */
  2168.                     tmp = addr;
  2169.                     addr = (addr + s->sh_addralign - 1) &
  2170.                         ~(s->sh_addralign - 1);
  2171.                     file_offset += (int) ( addr - tmp );
  2172.                     s->sh_offset = file_offset;
  2173.                     s->sh_addr = addr;
  2174.  
  2175.                     /* update program header infos */
  2176.                     if (ph->p_offset == 0) {
  2177.                         ph->p_offset = file_offset;
  2178.                         ph->p_vaddr = addr;
  2179.                         ph->p_paddr = ph->p_vaddr;
  2180.                     }
  2181.                     /* update dynamic relocation infos */
  2182.                     if (s->sh_type == SHT_RELX) {
  2183. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  2184.                         if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
  2185.                             dyninf->rel_addr = addr;
  2186.                             dyninf->rel_size += s->sh_size; /* XXX only first rel. */
  2187.                         }
  2188.                         if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
  2189.                             dyninf->bss_addr = addr;
  2190.                             dyninf->bss_size = s->sh_size; /* XXX only first rel. */
  2191.                         }
  2192. #else
  2193.                         if (dyninf->rel_size == 0)
  2194.                             dyninf->rel_addr = addr;
  2195.                         dyninf->rel_size += s->sh_size;
  2196. #endif
  2197.                     }
  2198.                     addr += s->sh_size;
  2199.                     if (s->sh_type != SHT_NOBITS)
  2200.                         file_offset += s->sh_size;
  2201.                 }
  2202.             }
  2203.             if (j == 0) {
  2204.                 /* Make the first PT_LOAD segment include the program
  2205.                    headers itself (and the ELF header as well), it'll
  2206.                    come out with same memory use but will make various
  2207.                    tools like binutils strip work better.  */
  2208.                 ph->p_offset &= ~(ph->p_align - 1);
  2209.                 ph->p_vaddr &= ~(ph->p_align - 1);
  2210.                 ph->p_paddr &= ~(ph->p_align - 1);
  2211.             }
  2212.             ph->p_filesz = file_offset - ph->p_offset;
  2213.             ph->p_memsz = addr - ph->p_vaddr;
  2214.             ph++;
  2215.             if (j == 0) {
  2216.                 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
  2217.                     /* if in the middle of a page, we duplicate the page in
  2218.                        memory so that one copy is RX and the other is RW */
  2219.                     if ((addr & (s_align - 1)) != 0)
  2220.                         addr += s_align;
  2221.                 } else {
  2222.                     addr = (addr + s_align - 1) & ~(s_align - 1);
  2223.                     file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
  2224.                 }
  2225.             }
  2226.         }
  2227.     }
  2228.  
  2229.     /* all other sections come after */
  2230.     for(i = 1; i < s1->nb_sections; i++) {
  2231.         s = s1->sections[i];
  2232.         if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
  2233.             continue;
  2234.         sec_order[sh_order_index++] = i;
  2235.  
  2236.         file_offset = (file_offset + s->sh_addralign - 1) &
  2237.             ~(s->sh_addralign - 1);
  2238.         s->sh_offset = file_offset;
  2239.         if (s->sh_type != SHT_NOBITS)
  2240.             file_offset += s->sh_size;
  2241.     }
  2242.  
  2243.     return file_offset;
  2244. }
  2245.  
  2246. static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
  2247.                                  Section *dynamic)
  2248. {
  2249.     ElfW(Phdr) *ph;
  2250.  
  2251.     /* if interpreter, then add corresponding program header */
  2252.     if (interp) {
  2253.         ph = &phdr[0];
  2254.  
  2255.         if (HAVE_PHDR)
  2256.         {
  2257.             int len = phnum * sizeof(ElfW(Phdr));
  2258.  
  2259.             ph->p_type = PT_PHDR;
  2260.             ph->p_offset = sizeof(ElfW(Ehdr));
  2261.             ph->p_vaddr = interp->sh_addr - len;
  2262.             ph->p_paddr = ph->p_vaddr;
  2263.             ph->p_filesz = ph->p_memsz = len;
  2264.             ph->p_flags = PF_R | PF_X;
  2265.             ph->p_align = 4; /* interp->sh_addralign; */
  2266.             ph++;
  2267.         }
  2268.  
  2269.         ph->p_type = PT_INTERP;
  2270.         ph->p_offset = interp->sh_offset;
  2271.         ph->p_vaddr = interp->sh_addr;
  2272.         ph->p_paddr = ph->p_vaddr;
  2273.         ph->p_filesz = interp->sh_size;
  2274.         ph->p_memsz = interp->sh_size;
  2275.         ph->p_flags = PF_R;
  2276.         ph->p_align = interp->sh_addralign;
  2277.     }
  2278.  
  2279.     /* if dynamic section, then add corresponding program header */
  2280.     if (dynamic) {
  2281.         ph = &phdr[phnum - 1];
  2282.  
  2283.         ph->p_type = PT_DYNAMIC;
  2284.         ph->p_offset = dynamic->sh_offset;
  2285.         ph->p_vaddr = dynamic->sh_addr;
  2286.         ph->p_paddr = ph->p_vaddr;
  2287.         ph->p_filesz = dynamic->sh_size;
  2288.         ph->p_memsz = dynamic->sh_size;
  2289.         ph->p_flags = PF_R | PF_W;
  2290.         ph->p_align = dynamic->sh_addralign;
  2291.     }
  2292. }
  2293.  
  2294. /* Fill the dynamic section with tags describing the address and size of
  2295.    sections */
  2296. static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
  2297. {
  2298.     Section *dynamic;
  2299.  
  2300.     dynamic = dyninf->dynamic;
  2301.  
  2302.     /* put dynamic section entries */
  2303.     dynamic->data_offset = dyninf->dyn_rel_off;
  2304.     put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
  2305.     put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
  2306.     put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
  2307.     put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
  2308.     put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
  2309. #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
  2310.     put_dt(dynamic, DT_RELA, dyninf->rel_addr);
  2311.     put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
  2312.     put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
  2313. #else
  2314. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  2315.     put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
  2316.     put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
  2317.     put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
  2318.     put_dt(dynamic, DT_PLTREL, DT_REL);
  2319.     put_dt(dynamic, DT_REL, dyninf->bss_addr);
  2320.     put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
  2321. #else
  2322.     put_dt(dynamic, DT_REL, dyninf->rel_addr);
  2323.     put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
  2324.     put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
  2325. #endif
  2326. #endif
  2327.     if (s1->do_debug)
  2328.         put_dt(dynamic, DT_DEBUG, 0);
  2329.     put_dt(dynamic, DT_NULL, 0);
  2330. }
  2331.  
  2332. /* Relocate remaining sections and symbols (that is those not related to
  2333.    dynamic linking) */
  2334. static int final_sections_reloc(TCCState *s1)
  2335. {
  2336.     int i;
  2337.     Section *s;
  2338.  
  2339.     relocate_syms(s1, 0);
  2340.  
  2341.     if (s1->nb_errors != 0)
  2342.         return -1;
  2343.  
  2344.     /* relocate sections */
  2345.     /* XXX: ignore sections with allocated relocations ? */
  2346.     for(i = 1; i < s1->nb_sections; i++) {
  2347.         s = s1->sections[i];
  2348. #ifdef TCC_TARGET_I386
  2349.         if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
  2350.         /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
  2351.         checking is removed */
  2352. #else
  2353.         if (s->reloc && s != s1->got)
  2354.         /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
  2355. #endif
  2356.             relocate_section(s1, s);
  2357.     }
  2358.  
  2359.     /* relocate relocation entries if the relocation tables are
  2360.        allocated in the executable */
  2361.     for(i = 1; i < s1->nb_sections; i++) {
  2362.         s = s1->sections[i];
  2363.         if ((s->sh_flags & SHF_ALLOC) &&
  2364.             s->sh_type == SHT_RELX) {
  2365.             relocate_rel(s1, s);
  2366.         }
  2367.     }
  2368.     return 0;
  2369. }
  2370.  
  2371. /* Create an ELF file on disk.
  2372.    This function handle ELF specific layout requirements */
  2373. static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
  2374.                            int file_offset, int *sec_order)
  2375. {
  2376.     int i, shnum, offset, size, file_type;
  2377.     Section *s;
  2378.     ElfW(Ehdr) ehdr;
  2379.     ElfW(Shdr) shdr, *sh;
  2380.  
  2381.     file_type = s1->output_type;
  2382.     shnum = s1->nb_sections;
  2383.  
  2384.     memset(&ehdr, 0, sizeof(ehdr));
  2385.  
  2386.     if (phnum > 0) {
  2387.         ehdr.e_phentsize = sizeof(ElfW(Phdr));
  2388.         ehdr.e_phnum = phnum;
  2389.         ehdr.e_phoff = sizeof(ElfW(Ehdr));
  2390.     }
  2391.  
  2392.     /* align to 4 */
  2393.     file_offset = (file_offset + 3) & -4;
  2394.  
  2395.     /* fill header */
  2396.     ehdr.e_ident[0] = ELFMAG0;
  2397.     ehdr.e_ident[1] = ELFMAG1;
  2398.     ehdr.e_ident[2] = ELFMAG2;
  2399.     ehdr.e_ident[3] = ELFMAG3;
  2400.     ehdr.e_ident[4] = ELFCLASSW;
  2401.     ehdr.e_ident[5] = ELFDATA2LSB;
  2402.     ehdr.e_ident[6] = EV_CURRENT;
  2403. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  2404.     ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
  2405. #endif
  2406. #ifdef TCC_TARGET_ARM
  2407. #ifdef TCC_ARM_EABI
  2408.     ehdr.e_ident[EI_OSABI] = 0;
  2409.     ehdr.e_flags = EF_ARM_EABI_VER4;
  2410.     if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
  2411.         ehdr.e_flags |= EF_ARM_HASENTRY;
  2412.     if (s1->float_abi == ARM_HARD_FLOAT)
  2413.         ehdr.e_flags |= EF_ARM_VFP_FLOAT;
  2414.     else
  2415.         ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
  2416. #else
  2417.     ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
  2418. #endif
  2419. #endif
  2420.     switch(file_type) {
  2421.     default:
  2422.     case TCC_OUTPUT_EXE:
  2423.         ehdr.e_type = ET_EXEC;
  2424.         ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
  2425.         break;
  2426.     case TCC_OUTPUT_DLL:
  2427.         ehdr.e_type = ET_DYN;
  2428.         ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
  2429.         break;
  2430.     case TCC_OUTPUT_OBJ:
  2431.         ehdr.e_type = ET_REL;
  2432.         break;
  2433.     }
  2434.     ehdr.e_machine = EM_TCC_TARGET;
  2435.     ehdr.e_version = EV_CURRENT;
  2436.     ehdr.e_shoff = file_offset;
  2437.     ehdr.e_ehsize = sizeof(ElfW(Ehdr));
  2438.     ehdr.e_shentsize = sizeof(ElfW(Shdr));
  2439.     ehdr.e_shnum = shnum;
  2440.     ehdr.e_shstrndx = shnum - 1;
  2441.  
  2442.     fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
  2443.     fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
  2444.     offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
  2445.  
  2446.     sort_syms(s1, symtab_section);
  2447.     for(i = 1; i < s1->nb_sections; i++) {
  2448.         s = s1->sections[sec_order[i]];
  2449.         if (s->sh_type != SHT_NOBITS) {
  2450.             if (s->sh_type == SHT_DYNSYM)
  2451.                 patch_dynsym_undef(s1, s);
  2452.             while (offset < s->sh_offset) {
  2453.                 fputc(0, f);
  2454.                 offset++;
  2455.             }
  2456.             size = s->sh_size;
  2457.             if (size)
  2458.                 fwrite(s->data, 1, size, f);
  2459.             offset += size;
  2460.         }
  2461.     }
  2462.  
  2463.     /* output section headers */
  2464.     while (offset < ehdr.e_shoff) {
  2465.         fputc(0, f);
  2466.         offset++;
  2467.     }
  2468.  
  2469.     for(i = 0; i < s1->nb_sections; i++) {
  2470.         sh = &shdr;
  2471.         memset(sh, 0, sizeof(ElfW(Shdr)));
  2472.         s = s1->sections[i];
  2473.         if (s) {
  2474.             sh->sh_name = s->sh_name;
  2475.             sh->sh_type = s->sh_type;
  2476.             sh->sh_flags = s->sh_flags;
  2477.             sh->sh_entsize = s->sh_entsize;
  2478.             sh->sh_info = s->sh_info;
  2479.             if (s->link)
  2480.                 sh->sh_link = s->link->sh_num;
  2481.             sh->sh_addralign = s->sh_addralign;
  2482.             sh->sh_addr = s->sh_addr;
  2483.             sh->sh_offset = s->sh_offset;
  2484.             sh->sh_size = s->sh_size;
  2485.         }
  2486.         fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
  2487.     }
  2488. }
  2489.  
  2490. /* Write an elf, coff or "binary" file */
  2491. static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
  2492.                               ElfW(Phdr) *phdr, int file_offset, int *sec_order)
  2493. {
  2494.     int fd, mode, file_type;
  2495.     FILE *f;
  2496.  
  2497.     file_type = s1->output_type;
  2498.     if (file_type == TCC_OUTPUT_OBJ)
  2499.         mode = 0666;
  2500.     else
  2501.         mode = 0777;
  2502.     unlink(filename);
  2503.     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
  2504.     if (fd < 0) {
  2505.         tcc_error_noabort("could not write '%s'", filename);
  2506.         return -1;
  2507.     }
  2508.     f = fdopen(fd, "wb");
  2509.     if (s1->verbose)
  2510.         printf("<- %s\n", filename);
  2511.  
  2512. #ifdef TCC_TARGET_COFF
  2513.     if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
  2514.         tcc_output_coff(s1, f);
  2515.     else
  2516. #endif
  2517.     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
  2518.         tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
  2519.     else
  2520.         tcc_output_binary(s1, f, sec_order);
  2521.     fclose(f);
  2522.  
  2523.     return 0;
  2524. }
  2525.  
  2526. /* Output an elf, coff or binary file */
  2527. /* XXX: suppress unneeded sections */
  2528. static int elf_output_file(TCCState *s1, const char *filename)
  2529. {
  2530.     int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
  2531.     struct dyn_inf dyninf;
  2532.     ElfW(Phdr) *phdr;
  2533.     ElfW(Sym) *sym;
  2534.     Section *strsec, *interp, *dynamic, *dynstr;
  2535.  
  2536.     file_type = s1->output_type;
  2537.     s1->nb_errors = 0;
  2538.  
  2539.     /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
  2540.     if (file_type != TCC_OUTPUT_OBJ) {
  2541.         tcc_add_runtime(s1);
  2542.     }
  2543.  
  2544.     phdr = NULL;
  2545.     sec_order = NULL;
  2546.     interp = dynamic = dynstr = NULL; /* avoid warning */
  2547.     dyninf.dyn_rel_off = 0; /* avoid warning */
  2548.  
  2549.     if (file_type != TCC_OUTPUT_OBJ) {
  2550.         relocate_common_syms();
  2551.  
  2552.         tcc_add_linker_symbols(s1);
  2553.  
  2554.         if (!s1->static_link) {
  2555.             if (file_type == TCC_OUTPUT_EXE) {
  2556.                 char *ptr;
  2557.                 /* allow override the dynamic loader */
  2558.                 const char *elfint = getenv("LD_SO");
  2559.                 if (elfint == NULL)
  2560.                     elfint = DEFAULT_ELFINTERP(s1);
  2561.                 /* add interpreter section only if executable */
  2562.                 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
  2563.                 interp->sh_addralign = 1;
  2564.                 ptr = section_ptr_add(interp, 1 + strlen(elfint));
  2565.                 strcpy(ptr, elfint);
  2566.             }
  2567.  
  2568.             /* add dynamic symbol table */
  2569.             s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
  2570.                                     ".dynstr",
  2571.                                     ".hash", SHF_ALLOC);
  2572.             dynstr = s1->dynsym->link;
  2573.  
  2574.             /* add dynamic section */
  2575.             dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
  2576.                                   SHF_ALLOC | SHF_WRITE);
  2577.             dynamic->link = dynstr;
  2578.             dynamic->sh_entsize = sizeof(ElfW(Dyn));
  2579.  
  2580.             build_got(s1);
  2581.  
  2582.             if (file_type == TCC_OUTPUT_EXE) {
  2583.                 bind_exe_dynsyms(s1);
  2584.  
  2585.                 if (s1->nb_errors) {
  2586.                     ret = -1;
  2587.                     goto the_end;
  2588.                 }
  2589.  
  2590.                 bind_libs_dynsyms(s1);
  2591.             } else /* shared library case: simply export all global symbols */
  2592.                 export_global_syms(s1);
  2593.  
  2594.             build_got_entries(s1);
  2595.  
  2596.             /* add a list of needed dlls */
  2597.             for(i = 0; i < s1->nb_loaded_dlls; i++) {
  2598.                 DLLReference *dllref = s1->loaded_dlls[i];
  2599.                 if (dllref->level == 0)
  2600.                     put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
  2601.             }
  2602.  
  2603.             if (s1->rpath)
  2604.                 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
  2605.  
  2606.             /* XXX: currently, since we do not handle PIC code, we
  2607.                must relocate the readonly segments */
  2608.             if (file_type == TCC_OUTPUT_DLL) {
  2609.                 if (s1->soname)
  2610.                     put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
  2611.                 put_dt(dynamic, DT_TEXTREL, 0);
  2612.             }
  2613.  
  2614.             if (s1->symbolic)
  2615.                 put_dt(dynamic, DT_SYMBOLIC, 0);
  2616.  
  2617.             /* add necessary space for other entries */
  2618.             dyninf.dyn_rel_off = dynamic->data_offset;
  2619.             dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
  2620.         } else {
  2621.             /* still need to build got entries in case of static link */
  2622.             build_got_entries(s1);
  2623.         }
  2624.     }
  2625.  
  2626.     /* we add a section for symbols */
  2627.     strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
  2628.     put_elf_str(strsec, "");
  2629.  
  2630.     /* compute number of sections */
  2631.     shnum = s1->nb_sections;
  2632.  
  2633.     /* this array is used to reorder sections in the output file */
  2634.     sec_order = tcc_malloc(sizeof(int) * shnum);
  2635.     sec_order[0] = 0;
  2636.  
  2637.     /* compute number of program headers */
  2638.     switch(file_type) {
  2639.     default:
  2640.     case TCC_OUTPUT_OBJ:
  2641.         phnum = 0;
  2642.         break;
  2643.     case TCC_OUTPUT_EXE:
  2644.         if (!s1->static_link)
  2645.             phnum = 4 + HAVE_PHDR;
  2646.         else
  2647.             phnum = 2;
  2648.         break;
  2649.     case TCC_OUTPUT_DLL:
  2650.         phnum = 3;
  2651.         break;
  2652.     }
  2653.  
  2654.     /* Allocate strings for section names */
  2655.     alloc_sec_names(s1, file_type, strsec);
  2656.  
  2657.     /* allocate program segment headers */
  2658.     phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
  2659.  
  2660.     /* compute section to program header mapping */
  2661.     file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
  2662.                                   sec_order);
  2663.  
  2664.     /* Fill remaining program header and finalize relocation related to dynamic
  2665.        linking. */
  2666.     if (phnum > 0) {
  2667.         fill_unloadable_phdr(phdr, phnum, interp, dynamic);
  2668.         if (dynamic) {
  2669.             dyninf.dynamic = dynamic;
  2670.             dyninf.dynstr = dynstr;
  2671.  
  2672.             fill_dynamic(s1, &dyninf);
  2673.  
  2674.             /* put in GOT the dynamic section address and relocate PLT */
  2675.             write32le(s1->got->data, dynamic->sh_addr);
  2676.             if (file_type == TCC_OUTPUT_EXE
  2677. #if defined(TCC_OUTPUT_DLL_WITH_PLT)
  2678.                 || file_type == TCC_OUTPUT_DLL
  2679. #endif
  2680.             )
  2681.                 relocate_plt(s1);
  2682.  
  2683.             /* relocate symbols in .dynsym now that final addresses are known */
  2684.             for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
  2685.                 if (sym->st_shndx == SHN_UNDEF) {
  2686.                     /* relocate to PLT if symbol corresponds to a PLT entry,
  2687.                        but not if it's a weak symbol */
  2688.                     if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
  2689.                         sym->st_value = 0;
  2690.                     else if (sym->st_value)
  2691.                         sym->st_value += s1->plt->sh_addr;
  2692.                 } else if (sym->st_shndx < SHN_LORESERVE) {
  2693.                     /* do symbol relocation */
  2694.                     sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
  2695.                 }
  2696.             }
  2697.         }
  2698.     }
  2699.  
  2700.     /* if building executable or DLL, then relocate each section
  2701.        except the GOT which is already relocated */
  2702.     if (file_type != TCC_OUTPUT_OBJ) {
  2703.         ret = final_sections_reloc(s1);
  2704.         if (ret)
  2705.             goto the_end;
  2706.     }
  2707.  
  2708.     /* Perform relocation to GOT or PLT entries */
  2709.     if (file_type == TCC_OUTPUT_EXE && s1->static_link)
  2710.         fill_got(s1);
  2711.  
  2712.     /* Create the ELF file with name 'filename' */
  2713.     ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
  2714.     if (s1->do_strip) {
  2715.         int rc;
  2716.         const char *strip_cmd = "sstrip "; // super strip utility from ELFkickers
  2717.         const char *null_dev = " 2> /dev/null";
  2718.         char buf[1050];
  2719.         snprintf(buf, sizeof(buf), "%s%s%s", strip_cmd, filename, null_dev);
  2720.         rc = system(buf);
  2721.         if (rc)
  2722.             system(buf+1);      // call a strip utility from binutils
  2723.     }
  2724.  the_end:
  2725.     tcc_free(s1->symtab_to_dynsym);
  2726.     tcc_free(sec_order);
  2727.     tcc_free(phdr);
  2728.     tcc_free(s1->sym_attrs);
  2729.     s1->sym_attrs = NULL;
  2730.     return ret;
  2731. }
  2732.  
  2733. LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
  2734. {
  2735.     int ret;
  2736. #ifdef TCC_TARGET_PE
  2737.     if (s->output_type != TCC_OUTPUT_OBJ) {
  2738.         ret = pe_output_file(s, filename);
  2739.     } else
  2740. #elif defined TCC_TARGET_MEOS
  2741.     if (s->output_type != TCC_OUTPUT_OBJ) {
  2742.         ret = tcc_output_me(s, filename);
  2743.     } else
  2744. #endif
  2745.         ret = elf_output_file(s, filename);
  2746.     return ret;
  2747. }
  2748.  
  2749. static void *load_data(int fd, unsigned long file_offset, unsigned long size)
  2750. {
  2751.     void *data;
  2752.  
  2753.     data = tcc_malloc(size);
  2754.     lseek(fd, file_offset, SEEK_SET);
  2755.     read(fd, data, size);
  2756.     return data;
  2757. }
  2758.  
  2759. typedef struct SectionMergeInfo {
  2760.     Section *s;            /* corresponding existing section */
  2761.     unsigned long offset;  /* offset of the new section in the existing section */
  2762.     uint8_t new_section;       /* true if section 's' was added */
  2763.     uint8_t link_once;         /* true if link once section */
  2764. } SectionMergeInfo;
  2765.  
  2766. /* load an object file and merge it with current files */
  2767. /* XXX: handle correctly stab (debug) info */
  2768. ST_FUNC int tcc_load_object_file(TCCState *s1,
  2769.                                 int fd, unsigned long file_offset)
  2770. {
  2771.     ElfW(Ehdr) ehdr;
  2772.     ElfW(Shdr) *shdr, *sh;
  2773.     int size, i, j, offset, offseti, nb_syms, sym_index, ret;
  2774.     unsigned char *strsec, *strtab;
  2775.     int *old_to_new_syms;
  2776.     char *sh_name, *name;
  2777.     SectionMergeInfo *sm_table, *sm;
  2778.     ElfW(Sym) *sym, *symtab;
  2779.     ElfW_Rel *rel;
  2780.     Section *s;
  2781.  
  2782.     int stab_index;
  2783.     int stabstr_index;
  2784.  
  2785.     stab_index = stabstr_index = 0;
  2786.  
  2787.     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
  2788.         goto fail1;
  2789.     if (ehdr.e_ident[0] != ELFMAG0 ||
  2790.         ehdr.e_ident[1] != ELFMAG1 ||
  2791.         ehdr.e_ident[2] != ELFMAG2 ||
  2792.         ehdr.e_ident[3] != ELFMAG3)
  2793.         goto fail1;
  2794.     /* test if object file */
  2795.     if (ehdr.e_type != ET_REL)
  2796.         goto fail1;
  2797.     /* test CPU specific stuff */
  2798.     if (ehdr.e_ident[5] != ELFDATA2LSB ||
  2799.         ehdr.e_machine != EM_TCC_TARGET) {
  2800.     fail1:
  2801.         tcc_error_noabort("invalid object file");
  2802.         return -1;
  2803.     }
  2804.     /* read sections */
  2805.     shdr = load_data(fd, file_offset + ehdr.e_shoff,
  2806.                      sizeof(ElfW(Shdr)) * ehdr.e_shnum);
  2807.     sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
  2808.  
  2809.     /* load section names */
  2810.     sh = &shdr[ehdr.e_shstrndx];
  2811.     strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
  2812.  
  2813.     /* load symtab and strtab */
  2814.     old_to_new_syms = NULL;
  2815.     symtab = NULL;
  2816.     strtab = NULL;
  2817.     nb_syms = 0;
  2818.     for(i = 1; i < ehdr.e_shnum; i++) {
  2819.         sh = &shdr[i];
  2820.         if (sh->sh_type == SHT_SYMTAB) {
  2821.             if (symtab) {
  2822.                 tcc_error_noabort("object must contain only one symtab");
  2823.             fail:
  2824.                 ret = -1;
  2825.                 goto the_end;
  2826.             }
  2827.             nb_syms = sh->sh_size / sizeof(ElfW(Sym));
  2828.             symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
  2829.             sm_table[i].s = symtab_section;
  2830.  
  2831.             /* now load strtab */
  2832.             sh = &shdr[sh->sh_link];
  2833.             strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
  2834.         }
  2835.     }
  2836.  
  2837.     /* now examine each section and try to merge its content with the
  2838.        ones in memory */
  2839.     for(i = 1; i < ehdr.e_shnum; i++) {
  2840.         /* no need to examine section name strtab */
  2841.         if (i == ehdr.e_shstrndx)
  2842.             continue;
  2843.         sh = &shdr[i];
  2844.         sh_name = (char *) strsec + sh->sh_name;
  2845.         /* ignore sections types we do not handle */
  2846.         if (sh->sh_type != SHT_PROGBITS &&
  2847.             sh->sh_type != SHT_RELX &&
  2848. #ifdef TCC_ARM_EABI
  2849.             sh->sh_type != SHT_ARM_EXIDX &&
  2850. #endif
  2851.             sh->sh_type != SHT_NOBITS &&
  2852.             sh->sh_type != SHT_PREINIT_ARRAY &&
  2853.             sh->sh_type != SHT_INIT_ARRAY &&
  2854.             sh->sh_type != SHT_FINI_ARRAY &&
  2855.             strcmp(sh_name, ".stabstr")
  2856.             )
  2857.             continue;
  2858.         if (sh->sh_addralign < 1)
  2859.             sh->sh_addralign = 1;
  2860.         /* find corresponding section, if any */
  2861.         for(j = 1; j < s1->nb_sections;j++) {
  2862.             s = s1->sections[j];
  2863.             if (!strcmp(s->name, sh_name)) {
  2864.                 if (!strncmp(sh_name, ".gnu.linkonce",
  2865.                              sizeof(".gnu.linkonce") - 1)) {
  2866.                     /* if a 'linkonce' section is already present, we
  2867.                        do not add it again. It is a little tricky as
  2868.                        symbols can still be defined in
  2869.                        it. */
  2870.                     sm_table[i].link_once = 1;
  2871.                     goto next;
  2872.                 } else {
  2873.                     goto found;
  2874.                 }
  2875.             }
  2876.         }
  2877.         /* not found: create new section */
  2878.         s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
  2879.         /* take as much info as possible from the section. sh_link and
  2880.            sh_info will be updated later */
  2881.         s->sh_addralign = sh->sh_addralign;
  2882.         s->sh_entsize = sh->sh_entsize;
  2883.         sm_table[i].new_section = 1;
  2884.     found:
  2885.         if (sh->sh_type != s->sh_type) {
  2886.             tcc_error_noabort("invalid section type");
  2887.             goto fail;
  2888.         }
  2889.  
  2890.         /* align start of section */
  2891.         offset = s->data_offset;
  2892.  
  2893.         if (0 == strcmp(sh_name, ".stab")) {
  2894.             stab_index = i;
  2895.             goto no_align;
  2896.         }
  2897.         if (0 == strcmp(sh_name, ".stabstr")) {
  2898.             stabstr_index = i;
  2899.             goto no_align;
  2900.         }
  2901.  
  2902.         size = sh->sh_addralign - 1;
  2903.         offset = (offset + size) & ~size;
  2904.         if (sh->sh_addralign > s->sh_addralign)
  2905.             s->sh_addralign = sh->sh_addralign;
  2906.         s->data_offset = offset;
  2907.     no_align:
  2908.         sm_table[i].offset = offset;
  2909.         sm_table[i].s = s;
  2910.         /* concatenate sections */
  2911.         size = sh->sh_size;
  2912.         if (sh->sh_type != SHT_NOBITS) {
  2913.             unsigned char *ptr;
  2914.             lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
  2915.             ptr = section_ptr_add(s, size);
  2916.             read(fd, ptr, size);
  2917.         } else {
  2918.             s->data_offset += size;
  2919.         }
  2920.     next: ;
  2921.     }
  2922.  
  2923.     /* gr relocate stab strings */
  2924.     if (stab_index && stabstr_index) {
  2925.         Stab_Sym *a, *b;
  2926.         unsigned o;
  2927.         s = sm_table[stab_index].s;
  2928.         a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
  2929.         b = (Stab_Sym *)(s->data + s->data_offset);
  2930.         o = sm_table[stabstr_index].offset;
  2931.         while (a < b)
  2932.             a->n_strx += o, a++;
  2933.     }
  2934.  
  2935.     /* second short pass to update sh_link and sh_info fields of new
  2936.        sections */
  2937.     for(i = 1; i < ehdr.e_shnum; i++) {
  2938.         s = sm_table[i].s;
  2939.         if (!s || !sm_table[i].new_section)
  2940.             continue;
  2941.         sh = &shdr[i];
  2942.         if (sh->sh_link > 0)
  2943.             s->link = sm_table[sh->sh_link].s;
  2944.         if (sh->sh_type == SHT_RELX) {
  2945.             s->sh_info = sm_table[sh->sh_info].s->sh_num;
  2946.             /* update backward link */
  2947.             s1->sections[s->sh_info]->reloc = s;
  2948.         }
  2949.     }
  2950.     sm = sm_table;
  2951.  
  2952.     /* resolve symbols */
  2953.     old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
  2954.  
  2955.     sym = symtab + 1;
  2956.     for(i = 1; i < nb_syms; i++, sym++) {
  2957.         if (sym->st_shndx != SHN_UNDEF &&
  2958.             sym->st_shndx < SHN_LORESERVE) {
  2959.             sm = &sm_table[sym->st_shndx];
  2960.             if (sm->link_once) {
  2961.                 /* if a symbol is in a link once section, we use the
  2962.                    already defined symbol. It is very important to get
  2963.                    correct relocations */
  2964.                 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
  2965.                     name = (char *) strtab + sym->st_name;
  2966.                     sym_index = find_elf_sym(symtab_section, name);
  2967.                     if (sym_index)
  2968.                         old_to_new_syms[i] = sym_index;
  2969.                 }
  2970.                 continue;
  2971.             }
  2972.             /* if no corresponding section added, no need to add symbol */
  2973.             if (!sm->s)
  2974.                 continue;
  2975.             /* convert section number */
  2976.             sym->st_shndx = sm->s->sh_num;
  2977.             /* offset value */
  2978.             sym->st_value += sm->offset;
  2979.         }
  2980.         /* add symbol */
  2981.         name = (char *) strtab + sym->st_name;
  2982.         sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
  2983.                                 sym->st_info, sym->st_other,
  2984.                                 sym->st_shndx, name);
  2985.         old_to_new_syms[i] = sym_index;
  2986.     }
  2987.  
  2988.     /* third pass to patch relocation entries */
  2989.     for(i = 1; i < ehdr.e_shnum; i++) {
  2990.         s = sm_table[i].s;
  2991.         if (!s)
  2992.             continue;
  2993.         sh = &shdr[i];
  2994.         offset = sm_table[i].offset;
  2995.         switch(s->sh_type) {
  2996.         case SHT_RELX:
  2997.             /* take relocation offset information */
  2998.             offseti = sm_table[sh->sh_info].offset;
  2999.             for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
  3000.                 int type;
  3001.                 unsigned sym_index;
  3002.                 /* convert symbol index */
  3003.                 type = ELFW(R_TYPE)(rel->r_info);
  3004.                 sym_index = ELFW(R_SYM)(rel->r_info);
  3005.                 /* NOTE: only one symtab assumed */
  3006.                 if (sym_index >= nb_syms)
  3007.                     goto invalid_reloc;
  3008.                 sym_index = old_to_new_syms[sym_index];
  3009.                 /* ignore link_once in rel section. */
  3010.                 if (!sym_index && !sm->link_once
  3011. #ifdef TCC_TARGET_ARM
  3012.                     && type != R_ARM_V4BX
  3013. #endif
  3014.                    ) {
  3015.                 invalid_reloc:
  3016.                     tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
  3017.                         i, strsec + sh->sh_name, rel->r_offset);
  3018.                     goto fail;
  3019.                 }
  3020.                 rel->r_info = ELFW(R_INFO)(sym_index, type);
  3021.                 /* offset the relocation offset */
  3022.                 rel->r_offset += offseti;
  3023. #ifdef TCC_TARGET_ARM
  3024.                 /* Jumps and branches from a Thumb code to a PLT entry need
  3025.                    special handling since PLT entries are ARM code.
  3026.                    Unconditional bl instructions referencing PLT entries are
  3027.                    handled by converting these instructions into blx
  3028.                    instructions. Other case of instructions referencing a PLT
  3029.                    entry require to add a Thumb stub before the PLT entry to
  3030.                    switch to ARM mode. We set bit plt_thumb_stub of the
  3031.                    attribute of a symbol to indicate such a case. */
  3032.                 if (type == R_ARM_THM_JUMP24)
  3033.                     alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;
  3034. #endif
  3035.             }
  3036.             break;
  3037.         default:
  3038.             break;
  3039.         }
  3040.     }
  3041.  
  3042.     ret = 0;
  3043.  the_end:
  3044.     tcc_free(symtab);
  3045.     tcc_free(strtab);
  3046.     tcc_free(old_to_new_syms);
  3047.     tcc_free(sm_table);
  3048.     tcc_free(strsec);
  3049.     tcc_free(shdr);
  3050.     return ret;
  3051. }
  3052.  
  3053. typedef struct ArchiveHeader {
  3054.     char ar_name[16];           /* name of this member */
  3055.     char ar_date[12];           /* file mtime */
  3056.     char ar_uid[6];             /* owner uid; printed as decimal */
  3057.     char ar_gid[6];             /* owner gid; printed as decimal */
  3058.     char ar_mode[8];            /* file mode, printed as octal   */
  3059.     char ar_size[10];           /* file size, printed as decimal */
  3060.     char ar_fmag[2];            /* should contain ARFMAG */
  3061. } ArchiveHeader;
  3062.  
  3063. static int get_be32(const uint8_t *b)
  3064. {
  3065.     return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
  3066. }
  3067.  
  3068. /* load only the objects which resolve undefined symbols */
  3069. static int tcc_load_alacarte(TCCState *s1, int fd, int size)
  3070. {
  3071.     int i, bound, nsyms, sym_index, off, ret;
  3072.     uint8_t *data;
  3073.     const char *ar_names, *p;
  3074.     const uint8_t *ar_index;
  3075.     ElfW(Sym) *sym;
  3076.  
  3077.     data = tcc_malloc(size);
  3078.     if (read(fd, data, size) != size)
  3079.         goto fail;
  3080.     nsyms = get_be32(data);
  3081.     ar_index = data + 4;
  3082.     ar_names = (char *) ar_index + nsyms * 4;
  3083.  
  3084.     do {
  3085.         bound = 0;
  3086.         for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
  3087.             sym_index = find_elf_sym(symtab_section, p);
  3088.             if(sym_index) {
  3089.                 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
  3090.                 if(sym->st_shndx == SHN_UNDEF) {
  3091.                     off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
  3092.                     ++bound;
  3093.                     lseek(fd, off, SEEK_SET);
  3094.                     if(tcc_load_object_file(s1, fd, off) < 0) {
  3095.                     fail:
  3096.                         ret = -1;
  3097.                         goto the_end;
  3098.                     }
  3099.                 }
  3100.             }
  3101.         }
  3102.     } while(bound);
  3103.     ret = 0;
  3104.  the_end:
  3105.     tcc_free(data);
  3106.     return ret;
  3107. }
  3108.  
  3109. /* load a '.a' file */
  3110. ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
  3111. {
  3112.     ArchiveHeader hdr;
  3113.     char ar_size[11];
  3114.     char ar_name[17];
  3115.     char magic[8];
  3116.     int size, len, i;
  3117.     unsigned long file_offset;
  3118.  
  3119.     /* skip magic which was already checked */
  3120.     read(fd, magic, sizeof(magic));
  3121.  
  3122.     for(;;) {
  3123.         len = read(fd, &hdr, sizeof(hdr));
  3124.         if (len == 0)
  3125.             break;
  3126.         if (len != sizeof(hdr)) {
  3127.             tcc_error_noabort("invalid archive");
  3128.             return -1;
  3129.         }
  3130.         memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
  3131.         ar_size[sizeof(hdr.ar_size)] = '\0';
  3132.         size = strtol(ar_size, NULL, 0);
  3133.         memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
  3134.         for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
  3135.             if (ar_name[i] != ' ')
  3136.                 break;
  3137.         }
  3138.         ar_name[i + 1] = '\0';
  3139.         file_offset = lseek(fd, 0, SEEK_CUR);
  3140.         /* align to even */
  3141.         size = (size + 1) & ~1;
  3142.         if (!strcmp(ar_name, "/")) {
  3143.             /* coff symbol table : we handle it */
  3144.             if(s1->alacarte_link)
  3145.                 return tcc_load_alacarte(s1, fd, size);
  3146.         } else if (!strcmp(ar_name, "//") ||
  3147.                    !strcmp(ar_name, "__.SYMDEF") ||
  3148.                    !strcmp(ar_name, "__.SYMDEF/") ||
  3149.                    !strcmp(ar_name, "ARFILENAMES/")) {
  3150.             /* skip symbol table or archive names */
  3151.         } else {
  3152.             if (tcc_load_object_file(s1, fd, file_offset) < 0)
  3153.                 return -1;
  3154.         }
  3155.         lseek(fd, file_offset + size, SEEK_SET);
  3156.     }
  3157.     return 0;
  3158. }
  3159.  
  3160. #if !defined(TCC_TARGET_PE) && !defined(TCC_TARGET_MEOS)
  3161. /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
  3162.    is referenced by the user (so it should be added as DT_NEEDED in
  3163.    the generated ELF file) */
  3164. ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
  3165. {
  3166.     ElfW(Ehdr) ehdr;
  3167.     ElfW(Shdr) *shdr, *sh, *sh1;
  3168.     int i, j, nb_syms, nb_dts, sym_bind, ret;
  3169.     ElfW(Sym) *sym, *dynsym;
  3170.     ElfW(Dyn) *dt, *dynamic;
  3171.     unsigned char *dynstr;
  3172.     const char *name, *soname;
  3173.     DLLReference *dllref;
  3174.  
  3175.     read(fd, &ehdr, sizeof(ehdr));
  3176.  
  3177.     /* test CPU specific stuff */
  3178.     if (ehdr.e_ident[5] != ELFDATA2LSB ||
  3179.         ehdr.e_machine != EM_TCC_TARGET) {
  3180.         tcc_error_noabort("bad architecture");
  3181.         return -1;
  3182.     }
  3183.  
  3184.     /* read sections */
  3185.     shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
  3186.  
  3187.     /* load dynamic section and dynamic symbols */
  3188.     nb_syms = 0;
  3189.     nb_dts = 0;
  3190.     dynamic = NULL;
  3191.     dynsym = NULL; /* avoid warning */
  3192.     dynstr = NULL; /* avoid warning */
  3193.     for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
  3194.         switch(sh->sh_type) {
  3195.         case SHT_DYNAMIC:
  3196.             nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
  3197.             dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
  3198.             break;
  3199.         case SHT_DYNSYM:
  3200.             nb_syms = sh->sh_size / sizeof(ElfW(Sym));
  3201.             dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
  3202.             sh1 = &shdr[sh->sh_link];
  3203.             dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
  3204.             break;
  3205.         default:
  3206.             break;
  3207.         }
  3208.     }
  3209.  
  3210.     /* compute the real library name */
  3211.     soname = tcc_basename(filename);
  3212.  
  3213.     for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
  3214.         if (dt->d_tag == DT_SONAME) {
  3215.             soname = (char *) dynstr + dt->d_un.d_val;
  3216.         }
  3217.     }
  3218.  
  3219.     /* if the dll is already loaded, do not load it */
  3220.     for(i = 0; i < s1->nb_loaded_dlls; i++) {
  3221.         dllref = s1->loaded_dlls[i];
  3222.         if (!strcmp(soname, dllref->name)) {
  3223.             /* but update level if needed */
  3224.             if (level < dllref->level)
  3225.                 dllref->level = level;
  3226.             ret = 0;
  3227.             goto the_end;
  3228.         }
  3229.     }
  3230.  
  3231.     /* add the dll and its level */
  3232.     dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
  3233.     dllref->level = level;
  3234.     strcpy(dllref->name, soname);
  3235.     dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
  3236.  
  3237.     /* add dynamic symbols in dynsym_section */
  3238.     for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
  3239.         sym_bind = ELFW(ST_BIND)(sym->st_info);
  3240.         if (sym_bind == STB_LOCAL)
  3241.             continue;
  3242.         name = (char *) dynstr + sym->st_name;
  3243.         add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
  3244.                     sym->st_info, sym->st_other, sym->st_shndx, name);
  3245.     }
  3246.  
  3247.     /* load all referenced DLLs */
  3248.     for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
  3249.         switch(dt->d_tag) {
  3250.         case DT_NEEDED:
  3251.             name = (char *) dynstr + dt->d_un.d_val;
  3252.             for(j = 0; j < s1->nb_loaded_dlls; j++) {
  3253.                 dllref = s1->loaded_dlls[j];
  3254.                 if (!strcmp(name, dllref->name))
  3255.                     goto already_loaded;
  3256.             }
  3257.             if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
  3258.                 tcc_error_noabort("referenced dll '%s' not found", name);
  3259.                 ret = -1;
  3260.                 goto the_end;
  3261.             }
  3262.         already_loaded:
  3263.             break;
  3264.         }
  3265.     }
  3266.     ret = 0;
  3267.  the_end:
  3268.     tcc_free(dynstr);
  3269.     tcc_free(dynsym);
  3270.     tcc_free(dynamic);
  3271.     tcc_free(shdr);
  3272.     return ret;
  3273. }
  3274.  
  3275. #define LD_TOK_NAME 256
  3276. #define LD_TOK_EOF  (-1)
  3277.  
  3278. /* return next ld script token */
  3279. static int ld_next(TCCState *s1, char *name, int name_size)
  3280. {
  3281.     int c;
  3282.     char *q;
  3283.  
  3284.  redo:
  3285.     switch(ch) {
  3286.     case ' ':
  3287.     case '\t':
  3288.     case '\f':
  3289.     case '\v':
  3290.     case '\r':
  3291.     case '\n':
  3292.         inp();
  3293.         goto redo;
  3294.     case '/':
  3295.         minp();
  3296.         if (ch == '*') {
  3297.             file->buf_ptr = parse_comment(file->buf_ptr,0);
  3298.             ch = file->buf_ptr[0];
  3299.             goto redo;
  3300.         } else {
  3301.             q = name;
  3302.             *q++ = '/';
  3303.             goto parse_name;
  3304.         }
  3305.         break;
  3306.     case '\\':
  3307.         ch = handle_eob();
  3308.         if (ch != '\\')
  3309.             goto redo;
  3310.         /* fall through */
  3311.     /* case 'a' ... 'z': */
  3312.     case 'a':
  3313.        case 'b':
  3314.        case 'c':
  3315.        case 'd':
  3316.        case 'e':
  3317.        case 'f':
  3318.        case 'g':
  3319.        case 'h':
  3320.        case 'i':
  3321.        case 'j':
  3322.        case 'k':
  3323.        case 'l':
  3324.        case 'm':
  3325.        case 'n':
  3326.        case 'o':
  3327.        case 'p':
  3328.        case 'q':
  3329.        case 'r':
  3330.        case 's':
  3331.        case 't':
  3332.        case 'u':
  3333.        case 'v':
  3334.        case 'w':
  3335.        case 'x':
  3336.        case 'y':
  3337.        case 'z':
  3338.     /* case 'A' ... 'z': */
  3339.     case 'A':
  3340.        case 'B':
  3341.        case 'C':
  3342.        case 'D':
  3343.        case 'E':
  3344.        case 'F':
  3345.        case 'G':
  3346.        case 'H':
  3347.        case 'I':
  3348.        case 'J':
  3349.        case 'K':
  3350.        case 'L':
  3351.        case 'M':
  3352.        case 'N':
  3353.        case 'O':
  3354.        case 'P':
  3355.        case 'Q':
  3356.        case 'R':
  3357.        case 'S':
  3358.        case 'T':
  3359.        case 'U':
  3360.        case 'V':
  3361.        case 'W':
  3362.        case 'X':
  3363.        case 'Y':
  3364.        case 'Z':
  3365.     case '_':
  3366.     case '.':
  3367.     case '$':
  3368.     case '~':
  3369.         q = name;
  3370.     parse_name:
  3371.         for(;;) {
  3372.             if (!((ch >= 'a' && ch <= 'z') ||
  3373.                   (ch >= 'A' && ch <= 'Z') ||
  3374.                   (ch >= '0' && ch <= '9') ||
  3375.                   strchr("/.-_+=$:\\,~", ch)))
  3376.                 break;
  3377.             if ((q - name) < name_size - 1) {
  3378.                 *q++ = ch;
  3379.             }
  3380.             minp();
  3381.         }
  3382.         *q = '\0';
  3383.         c = LD_TOK_NAME;
  3384.         break;
  3385.     case CH_EOF:
  3386.         c = LD_TOK_EOF;
  3387.         break;
  3388.     default:
  3389.         c = ch;
  3390.         inp();
  3391.         break;
  3392.     }
  3393.     return c;
  3394. }
  3395.  
  3396. static int ld_add_file(TCCState *s1, const char filename[])
  3397. {
  3398.     int ret;
  3399.  
  3400.     ret = tcc_add_file_internal(s1, filename, 0, TCC_FILETYPE_BINARY);
  3401.     if (ret)
  3402.         ret = tcc_add_dll(s1, filename, 0);
  3403.     return ret;
  3404. }
  3405.  
  3406. static inline int new_undef_syms(void)
  3407. {
  3408.     int ret = 0;
  3409.     ret = new_undef_sym;
  3410.     new_undef_sym = 0;
  3411.     return ret;
  3412. }
  3413.  
  3414. static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
  3415. {
  3416.     char filename[1024], libname[1024];
  3417.     int t, group, nblibs = 0, ret = 0;
  3418.     char **libs = NULL;
  3419.  
  3420.     group = !strcmp(cmd, "GROUP");
  3421.     if (!as_needed)
  3422.         new_undef_syms();
  3423.     t = ld_next(s1, filename, sizeof(filename));
  3424.     if (t != '(')
  3425.         expect("(");
  3426.     t = ld_next(s1, filename, sizeof(filename));
  3427.     for(;;) {
  3428.         libname[0] = '\0';
  3429.         if (t == LD_TOK_EOF) {
  3430.             tcc_error_noabort("unexpected end of file");
  3431.             ret = -1;
  3432.             goto lib_parse_error;
  3433.         } else if (t == ')') {
  3434.             break;
  3435.         } else if (t == '-') {
  3436.             t = ld_next(s1, filename, sizeof(filename));
  3437.             if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
  3438.                 tcc_error_noabort("library name expected");
  3439.                 ret = -1;
  3440.                 goto lib_parse_error;
  3441.             }
  3442.             pstrcpy(libname, sizeof libname, &filename[1]);
  3443.             if (s1->static_link) {
  3444.                 snprintf(filename, sizeof filename, "lib%s.a", libname);
  3445.             } else {
  3446.                 snprintf(filename, sizeof filename, "lib%s.so", libname);
  3447.             }
  3448.         } else if (t != LD_TOK_NAME) {
  3449.             tcc_error_noabort("filename expected");
  3450.             ret = -1;
  3451.             goto lib_parse_error;
  3452.         }
  3453.         if (!strcmp(filename, "AS_NEEDED")) {
  3454.             ret = ld_add_file_list(s1, cmd, 1);
  3455.             if (ret)
  3456.                 goto lib_parse_error;
  3457.         } else {
  3458.             /* TODO: Implement AS_NEEDED support. Ignore it for now */
  3459.             if (!as_needed) {
  3460.                 ret = ld_add_file(s1, filename);
  3461.                 if (ret)
  3462.                     goto lib_parse_error;
  3463.                 if (group) {
  3464.                     /* Add the filename *and* the libname to avoid future conversions */
  3465.                     dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
  3466.                     if (libname[0] != '\0')
  3467.                         dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
  3468.                 }
  3469.             }
  3470.         }
  3471.         t = ld_next(s1, filename, sizeof(filename));
  3472.         if (t == ',') {
  3473.             t = ld_next(s1, filename, sizeof(filename));
  3474.         }
  3475.     }
  3476.     if (group && !as_needed) {
  3477.         while (new_undef_syms()) {
  3478.             int i;
  3479.  
  3480.             for (i = 0; i < nblibs; i ++)
  3481.                 ld_add_file(s1, libs[i]);
  3482.         }
  3483.     }
  3484. lib_parse_error:
  3485.     dynarray_reset(&libs, &nblibs);
  3486.     return ret;
  3487. }
  3488.  
  3489. /* interpret a subset of GNU ldscripts to handle the dummy libc.so
  3490.    files */
  3491. ST_FUNC int tcc_load_ldscript(TCCState *s1)
  3492. {
  3493.     char cmd[64];
  3494.     char filename[1024];
  3495.     int t, ret;
  3496.  
  3497.     ch = handle_eob();
  3498.     for(;;) {
  3499.         t = ld_next(s1, cmd, sizeof(cmd));
  3500.         if (t == LD_TOK_EOF)
  3501.             return 0;
  3502.         else if (t != LD_TOK_NAME)
  3503.             return -1;
  3504.         if (!strcmp(cmd, "INPUT") ||
  3505.             !strcmp(cmd, "GROUP")) {
  3506.             ret = ld_add_file_list(s1, cmd, 0);
  3507.             if (ret)
  3508.                 return ret;
  3509.         } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
  3510.                    !strcmp(cmd, "TARGET")) {
  3511.             /* ignore some commands */
  3512.             t = ld_next(s1, cmd, sizeof(cmd));
  3513.             if (t != '(')
  3514.                 expect("(");
  3515.             for(;;) {
  3516.                 t = ld_next(s1, filename, sizeof(filename));
  3517.                 if (t == LD_TOK_EOF) {
  3518.                     tcc_error_noabort("unexpected end of file");
  3519.                     return -1;
  3520.                 } else if (t == ')') {
  3521.                     break;
  3522.                 }
  3523.             }
  3524.         } else {
  3525.             return -1;
  3526.         }
  3527.     }
  3528.     return 0;
  3529. }
  3530. #endif /* !TCC_TARGET_PE */
  3531.