12ec21a68SJordan K. Hubbard /* 22ec21a68SJordan K. Hubbard * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved. 32ec21a68SJordan K. Hubbard * 42ec21a68SJordan K. Hubbard * Redistribution and use in source and binary forms, with or without 52ec21a68SJordan K. Hubbard * modification, are permitted provided that the following conditions 62ec21a68SJordan K. Hubbard * are met: 72ec21a68SJordan K. Hubbard * 1. Redistributions of source code must retain the above copyright 82ec21a68SJordan K. Hubbard * notice, this list of conditions and the following disclaimer. 92ec21a68SJordan K. Hubbard * 2. Redistributions in binary form must reproduce the above copyright 102ec21a68SJordan K. Hubbard * notice, this list of conditions and the following disclaimer in the 112ec21a68SJordan K. Hubbard * documentation and/or other materials provided with the distribution. 122ec21a68SJordan K. Hubbard * 3. All advertising materials mentioning features or use of this software 132ec21a68SJordan K. Hubbard * must display the following acknowledgement: 142ec21a68SJordan K. Hubbard * This product includes software developed by Christopher G. Demetriou 152ec21a68SJordan K. Hubbard * for the NetBSD Project. 162ec21a68SJordan K. Hubbard * 4. The name of the author may not be used to endorse or promote products 172ec21a68SJordan K. Hubbard * derived from this software without specific prior written permission 182ec21a68SJordan K. Hubbard * 192ec21a68SJordan K. Hubbard * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 202ec21a68SJordan K. Hubbard * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 212ec21a68SJordan K. Hubbard * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 222ec21a68SJordan K. Hubbard * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 232ec21a68SJordan K. Hubbard * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 242ec21a68SJordan K. Hubbard * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 252ec21a68SJordan K. Hubbard * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 262ec21a68SJordan K. Hubbard * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 272ec21a68SJordan K. Hubbard * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 282ec21a68SJordan K. Hubbard * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 292ec21a68SJordan K. Hubbard */ 302ec21a68SJordan K. Hubbard 312ec21a68SJordan K. Hubbard #include <sys/cdefs.h> 322ec21a68SJordan K. Hubbard #ifndef lint 335e6220d9SDavid E. O'Brien #if 0 342ec21a68SJordan K. Hubbard __RCSID("$NetBSD: exec_elf32.c,v 1.4 1997/08/12 06:07:24 mikel Exp $"); 352ec21a68SJordan K. Hubbard #endif 365e6220d9SDavid E. O'Brien #endif 3790b77cf3SDavid E. O'Brien __FBSDID("$FreeBSD$"); 382ec21a68SJordan K. Hubbard 392ec21a68SJordan K. Hubbard #ifndef ELFSIZE 402ec21a68SJordan K. Hubbard #define ELFSIZE 32 412ec21a68SJordan K. Hubbard #endif 422ec21a68SJordan K. Hubbard 432ec21a68SJordan K. Hubbard #include <sys/types.h> 442d57da02SDavid E. O'Brien #include <sys/endian.h> 452ec21a68SJordan K. Hubbard #include <sys/stat.h> 462ec21a68SJordan K. Hubbard 472ec21a68SJordan K. Hubbard #include <errno.h> 482ec21a68SJordan K. Hubbard #include <stdio.h> 492ec21a68SJordan K. Hubbard #include <stdlib.h> 502ec21a68SJordan K. Hubbard #include <string.h> 512ec21a68SJordan K. Hubbard #include <unistd.h> 522ec21a68SJordan K. Hubbard 532ec21a68SJordan K. Hubbard #include "extern.h" 542ec21a68SJordan K. Hubbard 552ec21a68SJordan K. Hubbard #if (defined(NLIST_ELF32) && (ELFSIZE == 32)) || \ 562ec21a68SJordan K. Hubbard (defined(NLIST_ELF64) && (ELFSIZE == 64)) 572ec21a68SJordan K. Hubbard 5864b06e78SRuslan Ermilov #define __ELF_WORD_SIZE ELFSIZE 5964b06e78SRuslan Ermilov #if (ELFSIZE == 32) 6064b06e78SRuslan Ermilov #include <sys/elf32.h> 61d8d97708SRuslan Ermilov #define xewtoh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x)) 6282c7cf31SRuslan Ermilov #define htoxew(x) ((data == ELFDATA2MSB) ? htobe32(x) : htole32(x)) 6364b06e78SRuslan Ermilov #elif (ELFSIZE == 64) 6464b06e78SRuslan Ermilov #include <sys/elf64.h> 65d8d97708SRuslan Ermilov #define xewtoh(x) ((data == ELFDATA2MSB) ? be64toh(x) : le64toh(x)) 6682c7cf31SRuslan Ermilov #define htoxew(x) ((data == ELFDATA2MSB) ? htobe64(x) : htole64(x)) 6764b06e78SRuslan Ermilov #endif 6864b06e78SRuslan Ermilov #include <sys/elf_generic.h> 692ec21a68SJordan K. Hubbard 702ec21a68SJordan K. Hubbard #define CONCAT(x,y) __CONCAT(x,y) 712ec21a68SJordan K. Hubbard #define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x))) 722ec21a68SJordan K. Hubbard #define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y)))) 732ec21a68SJordan K. Hubbard #define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE)) 742ec21a68SJordan K. Hubbard #define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x))) 752ec21a68SJordan K. Hubbard 76d8d97708SRuslan Ermilov #define xe16toh(x) ((data == ELFDATA2MSB) ? be16toh(x) : le16toh(x)) 77d8d97708SRuslan Ermilov #define xe32toh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x)) 78d8d97708SRuslan Ermilov #define htoxe32(x) ((data == ELFDATA2MSB) ? htobe32(x) : htole32(x)) 79d8d97708SRuslan Ermilov 802ec21a68SJordan K. Hubbard struct listelem { 812ec21a68SJordan K. Hubbard struct listelem *next; 822ec21a68SJordan K. Hubbard void *mem; 832ec21a68SJordan K. Hubbard off_t file; 842ec21a68SJordan K. Hubbard size_t size; 852ec21a68SJordan K. Hubbard }; 862ec21a68SJordan K. Hubbard 872ec21a68SJordan K. Hubbard static ssize_t 882ec21a68SJordan K. Hubbard xreadatoff(int fd, void *buf, off_t off, size_t size, const char *fn) 892ec21a68SJordan K. Hubbard { 902ec21a68SJordan K. Hubbard ssize_t rv; 912ec21a68SJordan K. Hubbard 922ec21a68SJordan K. Hubbard if (lseek(fd, off, SEEK_SET) != off) { 932ec21a68SJordan K. Hubbard perror(fn); 942ec21a68SJordan K. Hubbard return -1; 952ec21a68SJordan K. Hubbard } 962ec21a68SJordan K. Hubbard if ((rv = read(fd, buf, size)) != size) { 972ec21a68SJordan K. Hubbard fprintf(stderr, "%s: read error: %s\n", fn, 982ec21a68SJordan K. Hubbard rv == -1 ? strerror(errno) : "short read"); 992ec21a68SJordan K. Hubbard return -1; 1002ec21a68SJordan K. Hubbard } 1012ec21a68SJordan K. Hubbard return size; 1022ec21a68SJordan K. Hubbard } 1032ec21a68SJordan K. Hubbard 1042ec21a68SJordan K. Hubbard static ssize_t 1052ec21a68SJordan K. Hubbard xwriteatoff(int fd, void *buf, off_t off, size_t size, const char *fn) 1062ec21a68SJordan K. Hubbard { 1072ec21a68SJordan K. Hubbard ssize_t rv; 1082ec21a68SJordan K. Hubbard 1092ec21a68SJordan K. Hubbard if (lseek(fd, off, SEEK_SET) != off) { 1102ec21a68SJordan K. Hubbard perror(fn); 1112ec21a68SJordan K. Hubbard return -1; 1122ec21a68SJordan K. Hubbard } 1132ec21a68SJordan K. Hubbard if ((rv = write(fd, buf, size)) != size) { 1142ec21a68SJordan K. Hubbard fprintf(stderr, "%s: write error: %s\n", fn, 1152ec21a68SJordan K. Hubbard rv == -1 ? strerror(errno) : "short write"); 1162ec21a68SJordan K. Hubbard return -1; 1172ec21a68SJordan K. Hubbard } 1182ec21a68SJordan K. Hubbard return size; 1192ec21a68SJordan K. Hubbard } 1202ec21a68SJordan K. Hubbard 1212ec21a68SJordan K. Hubbard static void * 1222ec21a68SJordan K. Hubbard xmalloc(size_t size, const char *fn, const char *use) 1232ec21a68SJordan K. Hubbard { 1242ec21a68SJordan K. Hubbard void *rv; 1252ec21a68SJordan K. Hubbard 1262ec21a68SJordan K. Hubbard rv = malloc(size); 1272ec21a68SJordan K. Hubbard if (rv == NULL) 1282ec21a68SJordan K. Hubbard fprintf(stderr, "%s: out of memory (allocating for %s)\n", 1292ec21a68SJordan K. Hubbard fn, use); 1302ec21a68SJordan K. Hubbard return (rv); 1312ec21a68SJordan K. Hubbard } 1322ec21a68SJordan K. Hubbard 133*7420b323SAdrian Chadd static void * 134*7420b323SAdrian Chadd xrealloc(void *ptr, size_t size, const char *fn, const char *use) 135*7420b323SAdrian Chadd { 136*7420b323SAdrian Chadd void *rv; 137*7420b323SAdrian Chadd 138*7420b323SAdrian Chadd rv = realloc(ptr, size); 139*7420b323SAdrian Chadd if (rv == NULL) { 140*7420b323SAdrian Chadd free(ptr); 141*7420b323SAdrian Chadd fprintf(stderr, "%s: out of memory (reallocating for %s)\n", 142*7420b323SAdrian Chadd fn, use); 143*7420b323SAdrian Chadd } 144*7420b323SAdrian Chadd return (rv); 145*7420b323SAdrian Chadd } 146*7420b323SAdrian Chadd 1472ec21a68SJordan K. Hubbard int 1482ec21a68SJordan K. Hubbard ELFNAMEEND(check)(int fd, const char *fn) 1492ec21a68SJordan K. Hubbard { 1502ec21a68SJordan K. Hubbard Elf_Ehdr eh; 1512ec21a68SJordan K. Hubbard struct stat sb; 152d8d97708SRuslan Ermilov unsigned char data; 1532ec21a68SJordan K. Hubbard 1542ec21a68SJordan K. Hubbard /* 1552ec21a68SJordan K. Hubbard * Check the header to maek sure it's an ELF file (of the 1562ec21a68SJordan K. Hubbard * appropriate size). 1572ec21a68SJordan K. Hubbard */ 1582ec21a68SJordan K. Hubbard if (fstat(fd, &sb) == -1) 1592ec21a68SJordan K. Hubbard return 0; 1602ec21a68SJordan K. Hubbard if (sb.st_size < sizeof eh) 1612ec21a68SJordan K. Hubbard return 0; 1622ec21a68SJordan K. Hubbard if (read(fd, &eh, sizeof eh) != sizeof eh) 1632ec21a68SJordan K. Hubbard return 0; 1642ec21a68SJordan K. Hubbard 1652ec21a68SJordan K. Hubbard if (IS_ELF(eh) == 0) 1662ec21a68SJordan K. Hubbard return 0; 1672ec21a68SJordan K. Hubbard 168d8d97708SRuslan Ermilov data = eh.e_ident[EI_DATA]; 169d8d97708SRuslan Ermilov 170d8d97708SRuslan Ermilov switch (xe16toh(eh.e_machine)) { 1712ec21a68SJordan K. Hubbard case EM_386: break; 1722ec21a68SJordan K. Hubbard case EM_ALPHA: break; 173ed575be4SOlivier Houchard #ifndef EM_ARM 174ed575be4SOlivier Houchard #define EM_ARM 40 175ed575be4SOlivier Houchard #endif 176ed575be4SOlivier Houchard case EM_ARM: break; 17722407452SDavid E. O'Brien #ifndef EM_MIPS 17822407452SDavid E. O'Brien #define EM_MIPS 8 17922407452SDavid E. O'Brien #endif 18022407452SDavid E. O'Brien #ifndef EM_MIPS_RS4_BE /* same as EM_MIPS_RS3_LE */ 18122407452SDavid E. O'Brien #define EM_MIPS_RS4_BE 10 18222407452SDavid E. O'Brien #endif 18322407452SDavid E. O'Brien case EM_MIPS: break; 18422407452SDavid E. O'Brien case /* EM_MIPS_RS3_LE */ EM_MIPS_RS4_BE: break; 1854192cfffSRuslan Ermilov #ifndef EM_IA_64 1864192cfffSRuslan Ermilov #define EM_IA_64 50 1874192cfffSRuslan Ermilov #endif 18866c795d4SRuslan Ermilov case EM_IA_64: break; 189930d8c70SDavid E. O'Brien #ifndef EM_PPC 190930d8c70SDavid E. O'Brien #define EM_PPC 20 191930d8c70SDavid E. O'Brien #endif 192930d8c70SDavid E. O'Brien case EM_PPC: break; 1938a10bad2SNathan Whitehorn #ifndef EM_PPC64 1948a10bad2SNathan Whitehorn #define EM_PPC64 21 1958a10bad2SNathan Whitehorn #endif 1968a10bad2SNathan Whitehorn case EM_PPC64: break; 1974192cfffSRuslan Ermilov #ifndef EM_SPARCV9 1984192cfffSRuslan Ermilov #define EM_SPARCV9 43 1994192cfffSRuslan Ermilov #endif 20066c795d4SRuslan Ermilov case EM_SPARCV9: break; 2018e81109eSPeter Wemm #ifndef EM_X86_64 2028e81109eSPeter Wemm #define EM_X86_64 62 2038e81109eSPeter Wemm #endif 2048e81109eSPeter Wemm case EM_X86_64: break; 2052ec21a68SJordan K. Hubbard /* ELFDEFNNAME(MACHDEP_ID_CASES) */ 2062ec21a68SJordan K. Hubbard 2072ec21a68SJordan K. Hubbard default: 2082ec21a68SJordan K. Hubbard return 0; 2092ec21a68SJordan K. Hubbard } 2102ec21a68SJordan K. Hubbard 2112ec21a68SJordan K. Hubbard return 1; 2122ec21a68SJordan K. Hubbard } 2132ec21a68SJordan K. Hubbard 214*7420b323SAdrian Chadd /* 215*7420b323SAdrian Chadd * This function 'hides' (some of) ELF executable file's symbols. 216*7420b323SAdrian Chadd * It hides them by renaming them to "_$$hide$$ <filename> <symbolname>". 217*7420b323SAdrian Chadd * Symbols in the global keep list, or which are marked as being undefined, 218*7420b323SAdrian Chadd * are left alone. 219*7420b323SAdrian Chadd * 220*7420b323SAdrian Chadd * An old version of this code shuffled various tables around, turning 221*7420b323SAdrian Chadd * global symbols to be hidden into local symbols. That lost on the 222*7420b323SAdrian Chadd * mips, because CALL16 relocs must reference global symbols, and, if 223*7420b323SAdrian Chadd * those symbols were being hidden, they were no longer global. 224*7420b323SAdrian Chadd * 225*7420b323SAdrian Chadd * The new renaming behaviour doesn't take global symbols out of the 226*7420b323SAdrian Chadd * namespace. However, it's ... unlikely that there will ever be 227*7420b323SAdrian Chadd * any collisions in practice because of the new method. 228*7420b323SAdrian Chadd */ 2292ec21a68SJordan K. Hubbard int 2302ec21a68SJordan K. Hubbard ELFNAMEEND(hide)(int fd, const char *fn) 2312ec21a68SJordan K. Hubbard { 2322ec21a68SJordan K. Hubbard Elf_Ehdr ehdr; 2332ec21a68SJordan K. Hubbard Elf_Shdr *shdrp = NULL, *symtabshdr, *strtabshdr; 2342ec21a68SJordan K. Hubbard Elf_Sym *symtabp = NULL; 2352ec21a68SJordan K. Hubbard char *strtabp = NULL; 236*7420b323SAdrian Chadd Elf_Size nsyms, nlocalsyms, ewi; 2372ec21a68SJordan K. Hubbard ssize_t shdrsize; 2382ec21a68SJordan K. Hubbard int rv, i, weird; 239*7420b323SAdrian Chadd size_t nstrtab_size, nstrtab_nextoff, fn_size; 240*7420b323SAdrian Chadd char *nstrtabp = NULL; 241d8d97708SRuslan Ermilov unsigned char data; 242*7420b323SAdrian Chadd Elf_Off maxoff, stroff; 243*7420b323SAdrian Chadd const char *weirdreason = NULL; 2442ec21a68SJordan K. Hubbard 2452ec21a68SJordan K. Hubbard rv = 0; 2462ec21a68SJordan K. Hubbard if (xreadatoff(fd, &ehdr, 0, sizeof ehdr, fn) != sizeof ehdr) 2472ec21a68SJordan K. Hubbard goto bad; 2482ec21a68SJordan K. Hubbard 249d8d97708SRuslan Ermilov data = ehdr.e_ident[EI_DATA]; 250d8d97708SRuslan Ermilov 251d8d97708SRuslan Ermilov shdrsize = xe16toh(ehdr.e_shnum) * xe16toh(ehdr.e_shentsize); 2522ec21a68SJordan K. Hubbard if ((shdrp = xmalloc(shdrsize, fn, "section header table")) == NULL) 2532ec21a68SJordan K. Hubbard goto bad; 254d8d97708SRuslan Ermilov if (xreadatoff(fd, shdrp, xewtoh(ehdr.e_shoff), shdrsize, fn) != 255d8d97708SRuslan Ermilov shdrsize) 2562ec21a68SJordan K. Hubbard goto bad; 2572ec21a68SJordan K. Hubbard 2582ec21a68SJordan K. Hubbard symtabshdr = strtabshdr = NULL; 2592ec21a68SJordan K. Hubbard weird = 0; 260*7420b323SAdrian Chadd maxoff = stroff = 0; 261d8d97708SRuslan Ermilov for (i = 0; i < xe16toh(ehdr.e_shnum); i++) { 262*7420b323SAdrian Chadd if (xewtoh(shdrp[i].sh_offset) > maxoff) 263*7420b323SAdrian Chadd maxoff = xewtoh(shdrp[i].sh_offset); 264d8d97708SRuslan Ermilov switch (xe32toh(shdrp[i].sh_type)) { 2652ec21a68SJordan K. Hubbard case SHT_SYMTAB: 2662ec21a68SJordan K. Hubbard if (symtabshdr != NULL) 2672ec21a68SJordan K. Hubbard weird = 1; 2682ec21a68SJordan K. Hubbard symtabshdr = &shdrp[i]; 269d8d97708SRuslan Ermilov strtabshdr = &shdrp[xe32toh(shdrp[i].sh_link)]; 270*7420b323SAdrian Chadd 271*7420b323SAdrian Chadd /* Check whether the string table is the last section */ 272*7420b323SAdrian Chadd stroff = xewtoh(shdrp[xe32toh(shdrp[i].sh_link)].sh_offset); 273*7420b323SAdrian Chadd if (!weird && xe32toh(shdrp[i].sh_link) != (xe16toh(ehdr.e_shnum) - 1)) { 274*7420b323SAdrian Chadd weird = 1; 275*7420b323SAdrian Chadd weirdreason = "string table not last section"; 276*7420b323SAdrian Chadd } 2772ec21a68SJordan K. Hubbard break; 2782ec21a68SJordan K. Hubbard } 2792ec21a68SJordan K. Hubbard } 280*7420b323SAdrian Chadd if (! weirdreason) 281*7420b323SAdrian Chadd weirdreason = "unsupported"; 2822ec21a68SJordan K. Hubbard if (symtabshdr == NULL) 2832ec21a68SJordan K. Hubbard goto out; 2842ec21a68SJordan K. Hubbard if (strtabshdr == NULL) 2852ec21a68SJordan K. Hubbard weird = 1; 286*7420b323SAdrian Chadd if (!weird && stroff != maxoff) { 287*7420b323SAdrian Chadd weird = 1; 288*7420b323SAdrian Chadd weirdreason = "string table section not last in file"; 289*7420b323SAdrian Chadd } 2902ec21a68SJordan K. Hubbard if (weird) { 291*7420b323SAdrian Chadd fprintf(stderr, "%s: weird executable (%s)\n", fn, weirdreason); 2922ec21a68SJordan K. Hubbard goto bad; 2932ec21a68SJordan K. Hubbard } 2942ec21a68SJordan K. Hubbard 2952ec21a68SJordan K. Hubbard /* 2962ec21a68SJordan K. Hubbard * load up everything we need 2972ec21a68SJordan K. Hubbard */ 2982ec21a68SJordan K. Hubbard 2992ec21a68SJordan K. Hubbard /* symbol table */ 300d8d97708SRuslan Ermilov if ((symtabp = xmalloc(xewtoh(symtabshdr->sh_size), fn, "symbol table")) 3012ec21a68SJordan K. Hubbard == NULL) 3022ec21a68SJordan K. Hubbard goto bad; 303d8d97708SRuslan Ermilov if (xreadatoff(fd, symtabp, xewtoh(symtabshdr->sh_offset), 304d8d97708SRuslan Ermilov xewtoh(symtabshdr->sh_size), fn) != xewtoh(symtabshdr->sh_size)) 3052ec21a68SJordan K. Hubbard goto bad; 3062ec21a68SJordan K. Hubbard 3072ec21a68SJordan K. Hubbard /* string table */ 308d8d97708SRuslan Ermilov if ((strtabp = xmalloc(xewtoh(strtabshdr->sh_size), fn, "string table")) 3092ec21a68SJordan K. Hubbard == NULL) 3102ec21a68SJordan K. Hubbard goto bad; 311d8d97708SRuslan Ermilov if (xreadatoff(fd, strtabp, xewtoh(strtabshdr->sh_offset), 312d8d97708SRuslan Ermilov xewtoh(strtabshdr->sh_size), fn) != xewtoh(strtabshdr->sh_size)) 3132ec21a68SJordan K. Hubbard goto bad; 3142ec21a68SJordan K. Hubbard 315*7420b323SAdrian Chadd nstrtab_size = 256; 316*7420b323SAdrian Chadd nstrtabp = xmalloc(nstrtab_size, fn, "new string table"); 317*7420b323SAdrian Chadd if (nstrtabp == NULL) 3182ec21a68SJordan K. Hubbard goto bad; 319*7420b323SAdrian Chadd nstrtab_nextoff = 0; 3202ec21a68SJordan K. Hubbard 321*7420b323SAdrian Chadd fn_size = strlen(fn); 3222ec21a68SJordan K. Hubbard 3232ec21a68SJordan K. Hubbard /* Prepare data structures for symbol movement. */ 324d8d97708SRuslan Ermilov nsyms = xewtoh(symtabshdr->sh_size) / xewtoh(symtabshdr->sh_entsize); 325d8d97708SRuslan Ermilov nlocalsyms = xe32toh(symtabshdr->sh_info); 3262ec21a68SJordan K. Hubbard 3272ec21a68SJordan K. Hubbard /* move symbols, making them local */ 328*7420b323SAdrian Chadd for (ewi = 0; ewi < nsyms; ewi++) { 329*7420b323SAdrian Chadd Elf_Sym *sp = &symtabp[ewi]; 330*7420b323SAdrian Chadd const char *symname = strtabp + xe32toh(sp->st_name); 331*7420b323SAdrian Chadd size_t newent_len; 3322ec21a68SJordan K. Hubbard /* 333*7420b323SAdrian Chadd * make sure there's size for the next entry, even if it's 334*7420b323SAdrian Chadd * as large as it can be. 335*7420b323SAdrian Chadd * 336*7420b323SAdrian Chadd * "_$$hide$$ <filename> <symname><NUL>" -> 337*7420b323SAdrian Chadd * 9 + 3 + sizes of fn and sym name 3382ec21a68SJordan K. Hubbard */ 339*7420b323SAdrian Chadd while ((nstrtab_size - nstrtab_nextoff) < 340*7420b323SAdrian Chadd strlen(symname) + fn_size + 12) { 341*7420b323SAdrian Chadd nstrtab_size *= 2; 342*7420b323SAdrian Chadd nstrtabp = xrealloc(nstrtabp, nstrtab_size, fn, 343*7420b323SAdrian Chadd "new string table"); 344*7420b323SAdrian Chadd if (nstrtabp == NULL) 345*7420b323SAdrian Chadd goto bad; 3462ec21a68SJordan K. Hubbard } 3472ec21a68SJordan K. Hubbard 348*7420b323SAdrian Chadd sp->st_name = htoxew(nstrtab_nextoff); 3492ec21a68SJordan K. Hubbard 350*7420b323SAdrian Chadd /* if it's a keeper or is undefined, don't rename it. */ 351*7420b323SAdrian Chadd if (in_keep_list(symname) || 352*7420b323SAdrian Chadd (xe16toh(sp->st_shndx) == SHN_UNDEF)) { 353*7420b323SAdrian Chadd newent_len = sprintf(nstrtabp + nstrtab_nextoff, 354*7420b323SAdrian Chadd "%s", symname) + 1; 355*7420b323SAdrian Chadd } else { 356*7420b323SAdrian Chadd newent_len = sprintf(nstrtabp + nstrtab_nextoff, 357*7420b323SAdrian Chadd "_$$hide$$ %s %s", fn, symname) + 1; 3582ec21a68SJordan K. Hubbard } 359*7420b323SAdrian Chadd nstrtab_nextoff += newent_len; 3602ec21a68SJordan K. Hubbard } 361*7420b323SAdrian Chadd strtabshdr->sh_size = htoxew(nstrtab_nextoff); 3622ec21a68SJordan K. Hubbard 3632ec21a68SJordan K. Hubbard /* 3642ec21a68SJordan K. Hubbard * write new tables to the file 3652ec21a68SJordan K. Hubbard */ 366d8d97708SRuslan Ermilov if (xwriteatoff(fd, shdrp, xewtoh(ehdr.e_shoff), shdrsize, fn) != 367d8d97708SRuslan Ermilov shdrsize) 3682ec21a68SJordan K. Hubbard goto bad; 369d8d97708SRuslan Ermilov if (xwriteatoff(fd, symtabp, xewtoh(symtabshdr->sh_offset), 370d8d97708SRuslan Ermilov xewtoh(symtabshdr->sh_size), fn) != xewtoh(symtabshdr->sh_size)) 3712ec21a68SJordan K. Hubbard goto bad; 372*7420b323SAdrian Chadd /* write new symbol table strings */ 373*7420b323SAdrian Chadd if ((size_t)xwriteatoff(fd, nstrtabp, xewtoh(strtabshdr->sh_offset), 374*7420b323SAdrian Chadd xewtoh(strtabshdr->sh_size), fn) != xewtoh(strtabshdr->sh_size)) 3752ec21a68SJordan K. Hubbard goto bad; 3762ec21a68SJordan K. Hubbard 3772ec21a68SJordan K. Hubbard out: 3782ec21a68SJordan K. Hubbard if (shdrp != NULL) 3792ec21a68SJordan K. Hubbard free(shdrp); 3802ec21a68SJordan K. Hubbard if (symtabp != NULL) 3812ec21a68SJordan K. Hubbard free(symtabp); 3822ec21a68SJordan K. Hubbard if (strtabp != NULL) 3832ec21a68SJordan K. Hubbard free(strtabp); 3842ec21a68SJordan K. Hubbard return (rv); 3852ec21a68SJordan K. Hubbard 3862ec21a68SJordan K. Hubbard bad: 3872ec21a68SJordan K. Hubbard rv = 1; 3882ec21a68SJordan K. Hubbard goto out; 3892ec21a68SJordan K. Hubbard } 3902ec21a68SJordan K. Hubbard 3912ec21a68SJordan K. Hubbard #endif /* include this size of ELF */ 392