exec_elf32.c revision 283260
144603Sdcs/* 244603Sdcs * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved. 344603Sdcs * 444603Sdcs * Redistribution and use in source and binary forms, with or without 544603Sdcs * modification, are permitted provided that the following conditions 644603Sdcs * are met: 744603Sdcs * 1. Redistributions of source code must retain the above copyright 844603Sdcs * notice, this list of conditions and the following disclaimer. 950477Speter * 2. Redistributions in binary form must reproduce the above copyright 1044603Sdcs * notice, this list of conditions and the following disclaimer in the 1144603Sdcs * documentation and/or other materials provided with the distribution. 1244603Sdcs * 3. All advertising materials mentioning features or use of this software 1344603Sdcs * must display the following acknowledgement: 1444603Sdcs * This product includes software developed by Christopher G. Demetriou 15280922Sdteske * for the NetBSD Project. 1644603Sdcs * 4. The name of the author may not be used to endorse or promote products 1765785Sdcs * derived from this software without specific prior written permission 1865785Sdcs * 19135986Sru * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2044603Sdcs * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2197201Sgordon * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2297201Sgordon * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2397201Sgordon * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2444603Sdcs * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2544603Sdcs * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2644603Sdcs * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2744603Sdcs * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2844603Sdcs * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2944603Sdcs */ 3044603Sdcs 3144603Sdcs#include <sys/cdefs.h> 3247171Sdcs#ifndef lint 3347171Sdcs#if 0 34230109Seadler__RCSID("$NetBSD: exec_elf32.c,v 1.6 1999/09/20 04:12:16 christos Exp $"); 3544603Sdcs#endif 3644603Sdcs#endif 37230109Seadler__FBSDID("$FreeBSD: stable/10/usr.sbin/crunch/crunchide/exec_elf32.c 283260 2015-05-21 19:16:28Z emaste $"); 3865939Sdcs 3944603Sdcs#ifndef ELFSIZE 4044603Sdcs#define ELFSIZE 32 4144603Sdcs#endif 42285882Strasz 43256377Smarkm#include <sys/types.h> 44256377Smarkm#include <sys/endian.h> 45284960Smarkm#include <sys/stat.h> 46284960Smarkm 47284960Smarkm#include <errno.h> 48284960Smarkm#include <limits.h> 49284960Smarkm#include <stddef.h> 50256377Smarkm#include <stdio.h> 51284960Smarkm#include <stdlib.h> 52284960Smarkm#include <string.h> 53284960Smarkm#include <unistd.h> 54284960Smarkm 55256377Smarkm#include "extern.h" 56285875Strasz 57282228Sscottl#if (defined(NLIST_ELF32) && (ELFSIZE == 32)) || \ 58285882Strasz (defined(NLIST_ELF64) && (ELFSIZE == 64)) 59282228Sscottl 60256377Smarkm#define __ELF_WORD_SIZE ELFSIZE 61282228Sscottl#if (ELFSIZE == 32) 62282228Sscottl#include <sys/elf32.h> 63282228Sscottl#define xewtoh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x)) 64282228Sscottl#define htoxew(x) ((data == ELFDATA2MSB) ? htobe32(x) : htole32(x)) 65282228Sscottl#define wewtoh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x)) 66282228Sscottl#define htowew(x) ((data == ELFDATA2MSB) ? htobe32(x) : htole32(x)) 67282228Sscottl#elif (ELFSIZE == 64) 68285875Strasz#include <sys/elf64.h> 69256377Smarkm#define xewtoh(x) ((data == ELFDATA2MSB) ? be64toh(x) : le64toh(x)) 70285881Strasz#define htoxew(x) ((data == ELFDATA2MSB) ? htobe64(x) : htole64(x)) 71285881Strasz/* elf64 Elf64_Word are 32 bits */ 72285881Strasz#define wewtoh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x)) 73285881Strasz#define htowew(x) ((data == ELFDATA2MSB) ? htobe32(x) : htole32(x)) 74285881Strasz#endif 75285881Strasz#include <sys/elf_generic.h> 76285881Strasz 77285881Strasz#define CONCAT(x,y) __CONCAT(x,y) 78285881Strasz#define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x))) 79285881Strasz#define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y)))) 8044603Sdcs#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE)) 8144603Sdcs#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x))) 8244603Sdcs 83257821Sdteske#define xe16toh(x) ((data == ELFDATA2MSB) ? be16toh(x) : le16toh(x)) 84257821Sdteske#define xe32toh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x)) 85146421Ssobomax#define htoxe32(x) ((data == ELFDATA2MSB) ? htobe32(x) : htole32(x)) 86146421Ssobomax 87146421Ssobomaxstruct shlayout { 88172327Sru Elf_Shdr *shdr; 89172327Sru void *bufp; 90280385Sdteske}; 91280385Sdteske 92281616Sdteskestatic ssize_t 93293001Sallanjudexreadatoff(int fd, void *buf, off_t off, size_t size, const char *fn) 94117090Sbrueffer{ 95257650Sdteske ssize_t rv; 96227727Smiwi 97149213Siedowse if (lseek(fd, off, SEEK_SET) != off) { 98148515Sbrian perror(fn); 9954247Sdcs return -1; 100133217Sjmg } 10152749Sdcs if ((size_t)(rv = read(fd, buf, size)) != size) { 10254247Sdcs fprintf(stderr, "%s: read error: %s\n", fn, 10354247Sdcs rv == -1 ? strerror(errno) : "short read"); 104224408Srodrigc return -1; 105224408Srodrigc } 106224408Srodrigc return size; 107224408Srodrigc} 108224408Srodrigc 109276087Sianstatic ssize_t 11044603Sdcsxwriteatoff(int fd, void *buf, off_t off, size_t size, const char *fn) 11144603Sdcs{ 11244603Sdcs ssize_t rv; 11344603Sdcs 11444603Sdcs if (lseek(fd, off, SEEK_SET) != off) { 11544603Sdcs perror(fn); 116148515Sbrian return -1; 117148515Sbrian } 118148515Sbrian if ((size_t)(rv = write(fd, buf, size)) != size) { 119148515Sbrian fprintf(stderr, "%s: write error: %s\n", fn, 120148515Sbrian rv == -1 ? strerror(errno) : "short write"); 121148515Sbrian return -1; 122148515Sbrian } 123150469Sru return size; 124148515Sbrian} 125148515Sbrian 126150469Srustatic void * 127150469Sruxmalloc(size_t size, const char *fn, const char *use) 128148515Sbrian{ 129148515Sbrian void *rv; 130148515Sbrian 131226833Spluknet rv = malloc(size); 13254265Smsmith if (rv == NULL) 133166486Simp fprintf(stderr, "%s: out of memory (allocating for %s)\n", 134166486Simp fn, use); 135166486Simp return (rv); 13644603Sdcs} 13744603Sdcs 13844603Sdcsstatic void * 13944603Sdcsxrealloc(void *ptr, size_t size, const char *fn, const char *use) 14044603Sdcs{ 14144603Sdcs void *rv; 142132853Sceri 14399332Smini rv = realloc(ptr, size); 14499332Smini if (rv == NULL) { 14599332Smini free(ptr); 14699332Smini fprintf(stderr, "%s: out of memory (reallocating for %s)\n", 14799332Smini fn, use); 14899332Smini } 14999332Smini return (rv); 15099332Smini} 15199332Smini 15299332Sminiint 15386902SrwatsonELFNAMEEND(check)(int fd, const char *fn) 154217689Spluknet{ 155148817Skrion Elf_Ehdr eh; 15699332Smini struct stat sb; 157202143Sbrooks unsigned char data; 15899332Smini 159225122Smarck /* 160225122Smarck * Check the header to maek sure it's an ELF file (of the 161102862Sbrooks * appropriate size). 162298831Spfg */ 16344603Sdcs if (fstat(fd, &sb) == -1) 16499332Smini return 0; 16544603Sdcs if (sb.st_size < (off_t)(sizeof eh)) 16695524Sdcs return 0; 16795524Sdcs if (read(fd, &eh, sizeof eh) != sizeof eh) 168125091Sdes return 0; 169268254Sjmg 17070706Sjhb if (IS_ELF(eh) == 0) 17170706Sjhb return 0; 17270706Sjhb 173111749Sharti data = eh.e_ident[EI_DATA]; 17444603Sdcs 17544603Sdcs switch (xe16toh(eh.e_machine)) { 17644603Sdcs case EM_386: break; 177285882Strasz case EM_ALPHA: break; 178209466Sbrucec#ifndef EM_ARM 179209466Sbrucec#define EM_ARM 40 180209466Sbrucec#endif 181209466Sbrucec case EM_ARM: break; 182209466Sbrucec#ifndef EM_MIPS 183209466Sbrucec#define EM_MIPS 8 184209466Sbrucec#endif 185209466Sbrucec#ifndef EM_MIPS_RS4_BE /* same as EM_MIPS_RS3_LE */ 186209466Sbrucec#define EM_MIPS_RS4_BE 10 187209466Sbrucec#endif 188209466Sbrucec case EM_MIPS: break; 189209466Sbrucec case /* EM_MIPS_RS3_LE */ EM_MIPS_RS4_BE: break; 190209466Sbrucec#ifndef EM_IA_64 191209466Sbrucec#define EM_IA_64 50 192209466Sbrucec#endif 193209466Sbrucec case EM_IA_64: break; 194209466Sbrucec#ifndef EM_PPC 195209466Sbrucec#define EM_PPC 20 196209466Sbrucec#endif 197209466Sbrucec case EM_PPC: break; 198209466Sbrucec#ifndef EM_PPC64 199209466Sbrucec#define EM_PPC64 21 200209466Sbrucec#endif 201209466Sbrucec case EM_PPC64: break; 202209466Sbrucec#ifndef EM_SPARCV9 203209466Sbrucec#define EM_SPARCV9 43 20444603Sdcs#endif 20544603Sdcs case EM_SPARCV9: break; 20644603Sdcs#ifndef EM_X86_64 20744603Sdcs#define EM_X86_64 62 20844603Sdcs#endif 20944603Sdcs case EM_X86_64: break; 21077034Sru/* ELFDEFNNAME(MACHDEP_ID_CASES) */ 211126455Sdes 212161286Sbrueffer default: 21377162Sru return 0; 214135986Sru } 215135986Sru 21663962Ssheldonh return 1; 21744603Sdcs} 21877034Sru 219168554Spjd/* 22044603Sdcs * This function 'hides' (some of) ELF executable file's symbols. 22144603Sdcs * It hides them by renaming them to "_$$hide$$ <filename> <symbolname>". 22244603Sdcs * Symbols in the global keep list, or which are marked as being undefined, 223152307Spjd * are left alone. 224152307Spjd * 225152307Spjd * An old version of this code shuffled various tables around, turning 226152307Spjd * global symbols to be hidden into local symbols. That lost on the 227152309Spjd * mips, because CALL16 relocs must reference global symbols, and, if 228152307Spjd * those symbols were being hidden, they were no longer global. 229152307Spjd * 230182194Smatteo * The new renaming behaviour doesn't take global symbols out of the 231152307Spjd * namespace. However, it's ... unlikely that there will ever be 232152309Spjd * any collisions in practice because of the new method. 233166003Smaxim */ 234152307Spjdint 235202437StraszELFNAMEEND(hide)(int fd, const char *fn) 236152307Spjd{ 237152307Spjd Elf_Ehdr ehdr; 238152307Spjd struct shlayout *layoutp = NULL; 239152307Spjd Elf_Shdr *shdrp = NULL, *symtabshdr, *strtabshdr, *shstrtabshdr; 240152309Spjd Elf_Shdr shdrshdr; 241152307Spjd Elf_Sym *symtabp = NULL; 24244603Sdcs char *shstrtabp = NULL, *strtabp = NULL; 24344603Sdcs Elf_Size nsyms, ewi; 24444603Sdcs Elf_Off off; 245209466Sbrucec ssize_t shdrsize; 246209466Sbrucec int rv, i, weird, l, m, r, strtabidx; 247209466Sbrucec size_t nstrtab_size, nstrtab_nextoff, fn_size, size; 248209466Sbrucec char *nstrtabp = NULL; 249209466Sbrucec unsigned char data; 250209466Sbrucec const char *weirdreason = NULL; 251209466Sbrucec void *buf; 252209466Sbrucec Elf_Half shnum; 253209466Sbrucec 254209466Sbrucec rv = 0; 255209466Sbrucec if (xreadatoff(fd, &ehdr, 0, sizeof ehdr, fn) != sizeof ehdr) 256209466Sbrucec goto bad; 25744603Sdcs 25844603Sdcs data = ehdr.e_ident[EI_DATA]; 25944603Sdcs shnum = xe16toh(ehdr.e_shnum); 26044603Sdcs 26144603Sdcs shdrsize = shnum * xe16toh(ehdr.e_shentsize); 26244603Sdcs if ((shdrp = xmalloc(shdrsize, fn, "section header table")) == NULL) 26344603Sdcs goto bad; 26444603Sdcs if (xreadatoff(fd, shdrp, xewtoh(ehdr.e_shoff), shdrsize, fn) != 26544603Sdcs shdrsize) 26644603Sdcs goto bad; 26744603Sdcs 26844603Sdcs symtabshdr = strtabshdr = shstrtabshdr = NULL; 26944603Sdcs weird = 0; 270286111Sed for (i = 0; i < shnum; i++) { 271286111Sed switch (xe32toh(shdrp[i].sh_type)) { 27244603Sdcs case SHT_SYMTAB: 27344603Sdcs if (symtabshdr != NULL) { 27444603Sdcs weird = 1; 27547173Sdcs weirdreason = "multiple symbol tables"; 27647173Sdcs } 27744603Sdcs symtabshdr = &shdrp[i]; 27844603Sdcs strtabshdr = &shdrp[xe32toh(shdrp[i].sh_link)]; 27944603Sdcs break; 28044603Sdcs case SHT_STRTAB: 28144603Sdcs if (i == xe16toh(ehdr.e_shstrndx)) 28244603Sdcs shstrtabshdr = &shdrp[i]; 28344603Sdcs break; 284166005Smaxim } 285166005Smaxim } 286195892Sbz if (symtabshdr == NULL) 287106335Smini goto out; 288106335Smini if (strtabshdr == NULL) { 289106335Smini weird = 1; 290106335Smini weirdreason = "string table does not exist"; 29144603Sdcs } 292106335Smini if (shstrtabshdr == NULL) { 29344603Sdcs weird = 1; 294126263Smlaier weirdreason = "section header string table does not exist"; 29544603Sdcs } 29644603Sdcs if (weirdreason == NULL) 29744603Sdcs weirdreason = "unsupported"; 29847175Sdcs if (weird) { 29947175Sdcs fprintf(stderr, "%s: weird executable (%s)\n", fn, weirdreason); 30047175Sdcs goto bad; 301218815Sdanger } 30254020Sdcs 303228576Sglebius /* 304183592Sstas * sort section layout table by offset 305179106Syongari */ 306193880Syongari layoutp = xmalloc((shnum + 1) * sizeof(struct shlayout), 307184870Syongari fn, "layout table"); 30855992Swpaul if (layoutp == NULL) 309148798Skrion goto bad; 310148817Skrion 311148817Skrion /* add a pseudo entry to represent the section header table */ 312161286Sbrueffer shdrshdr.sh_offset = ehdr.e_shoff; 313135986Sru shdrshdr.sh_size = htoxew(shdrsize); 314161286Sbrueffer shdrshdr.sh_addralign = htoxew(ELFSIZE / 8); 315218815Sdanger layoutp[shnum].shdr = &shdrshdr; 316209466Sbrucec 317204328Sweongyo /* insert and sort normal section headers */ 318219647Sdavidch for (i = shnum; i-- != 0;) { 319194246Smarius l = i + 1; 320106330Smini r = shnum; 321148817Skrion while (l <= r) { 322148817Skrion m = ( l + r) / 2; 323209466Sbrucec if (xewtoh(shdrp[i].sh_offset) > 32455017Swpaul xewtoh(layoutp[m].shdr->sh_offset)) 325161286Sbrueffer l = m + 1; 326166005Smaxim else 327166005Smaxim r = m - 1; 328161286Sbrueffer } 329115054Smurray 330106330Smini if (r != i) { 331207630Sdelphij memmove(&layoutp[i], &layoutp[i + 1], 332161286Sbrueffer sizeof(struct shlayout) * (r - i)); 333209466Sbrucec } 334166005Smaxim 335166005Smaxim layoutp[r].shdr = &shdrp[i]; 33654019Sdcs layoutp[r].bufp = NULL; 337158569Smarius } 338209466Sbrucec ++shnum; 339158569Smarius 340115054Smurray /* 341177693Sbrueffer * load up everything we need 342161286Sbrueffer */ 343166005Smaxim 344166005Smaxim /* load section string table for debug use */ 345209466Sbrucec if ((size = xewtoh(shstrtabshdr->sh_size)) == 0) 346161449Sbrueffer goto bad; 347177693Sbrueffer if ((shstrtabp = xmalloc(size, fn, "section string table")) == NULL) 348179343Syongari goto bad; 349218815Sdanger if ((size_t)xreadatoff(fd, shstrtabp, xewtoh(shstrtabshdr->sh_offset), 350158569Smarius size, fn) != size) 351166005Smaxim goto bad; 352166005Smaxim if (shstrtabp[size - 1] != '\0') 353177990Sweongyo goto bad; 354177990Sweongyo 355165145Syongari /* we need symtab, strtab, and everything behind strtab */ 356161449Sbrueffer strtabidx = INT_MAX; 357161286Sbrueffer for (i = 0; i < shnum; i++) { 358161448Sbrueffer if (layoutp[i].shdr == &shdrshdr) { 359161286Sbrueffer /* not load section header again */ 360177693Sbrueffer layoutp[i].bufp = shdrp; 361209466Sbrucec continue; 362106335Smini } 363177693Sbrueffer if (layoutp[i].shdr == shstrtabshdr) { 364135986Sru /* not load section string table again */ 36555017Swpaul layoutp[i].bufp = shstrtabp; 366148817Skrion continue; 367209466Sbrucec } 368209466Sbrucec 369182912Sjhb if (layoutp[i].shdr == strtabshdr) 37054019Sdcs strtabidx = i; 371207630Sdelphij if (layoutp[i].shdr == symtabshdr || i >= strtabidx) { 37254019Sdcs off = xewtoh(layoutp[i].shdr->sh_offset); 373161286Sbrueffer if ((size = xewtoh(layoutp[i].shdr->sh_size)) == 0) 374106330Smini goto bad; 375161286Sbrueffer layoutp[i].bufp = xmalloc(size, fn, 376161286Sbrueffer shstrtabp + xewtoh(layoutp[i].shdr->sh_name)); 37754019Sdcs if (layoutp[i].bufp == NULL) 37854019Sdcs goto bad; 379161286Sbrueffer if ((size_t)xreadatoff(fd, layoutp[i].bufp, off, size, fn) != 380106335Smini size) 381135986Sru goto bad; 382216829Syongari 383190789Sweongyo /* set symbol table and string table */ 384148817Skrion if (layoutp[i].shdr == symtabshdr) { 385181581Sweongyo symtabp = layoutp[i].bufp; 386177693Sbrueffer } else if (layoutp[i].shdr == strtabshdr) { 387187614Sweongyo strtabp = layoutp[i].bufp; 38854019Sdcs if (strtabp[size - 1] != '\0') 389106330Smini goto bad; 39054019Sdcs } 39155992Swpaul } 392177693Sbrueffer } 393106330Smini 39454019Sdcs nstrtab_size = 256; 395209466Sbrucec nstrtabp = xmalloc(nstrtab_size, fn, "new string table"); 39647175Sdcs if (nstrtabp == NULL) 397285875Strasz goto bad; 39847175Sdcs nstrtab_nextoff = 0; 39974212Sjhb 40074212Sjhb fn_size = strlen(fn); 40174212Sjhb 40274212Sjhb /* Prepare data structures for symbol movement. */ 40374212Sjhb nsyms = xewtoh(symtabshdr->sh_size) / xewtoh(symtabshdr->sh_entsize); 40474212Sjhb 40574212Sjhb /* move symbols, making them local */ 40674212Sjhb for (ewi = 0; ewi < nsyms; ewi++) { 40774212Sjhb Elf_Sym *sp = &symtabp[ewi]; 408135986Sru const char *symname = strtabp + xe32toh(sp->st_name); 409135986Sru size_t newent_len; 41074212Sjhb /* 41174212Sjhb * make sure there's size for the next entry, even if it's 412135986Sru * as large as it can be. 413135986Sru * 41474212Sjhb * "_$$hide$$ <filename> <symname><NUL>" -> 415135986Sru * 9 + 3 + sizes of fn and sym name 41674212Sjhb */ 417135986Sru while ((nstrtab_size - nstrtab_nextoff) < 41874212Sjhb strlen(symname) + fn_size + 12) { 419135986Sru nstrtab_size *= 2; 42074212Sjhb nstrtabp = xrealloc(nstrtabp, nstrtab_size, fn, 421166005Smaxim "new string table"); 422166005Smaxim if (nstrtabp == NULL) 423166004Smaxim goto bad; 42474212Sjhb } 42574212Sjhb 42674212Sjhb sp->st_name = htowew(nstrtab_nextoff); 42774212Sjhb 42874212Sjhb /* if it's a keeper or is undefined, don't rename it. */ 42974212Sjhb if (in_keep_list(symname) || 430166005Smaxim (xe16toh(sp->st_shndx) == SHN_UNDEF)) { 431166005Smaxim newent_len = sprintf(nstrtabp + nstrtab_nextoff, 432135986Sru "%s", symname) + 1; 43374212Sjhb } else { 434166005Smaxim newent_len = sprintf(nstrtabp + nstrtab_nextoff, 435166005Smaxim "_$$hide$$ %s %s", fn, symname) + 1; 43674212Sjhb } 437135986Sru nstrtab_nextoff += newent_len; 43874212Sjhb } 439285875Strasz strtabshdr->sh_size = htoxew(nstrtab_nextoff); 44074212Sjhb 44174212Sjhb /* 44274212Sjhb * update section header table in ascending order of offset 44374212Sjhb */ 444132248Stanimura for (i = strtabidx + 1; i < shnum; i++) { 44574212Sjhb Elf_Off off, align; 446135986Sru off = xewtoh(layoutp[i - 1].shdr->sh_offset) + 447152979Sariff xewtoh(layoutp[i - 1].shdr->sh_size); 44874212Sjhb align = xewtoh(layoutp[i].shdr->sh_addralign); 449135986Sru off = (off + (align - 1)) & ~(align - 1); 45074212Sjhb layoutp[i].shdr->sh_offset = htoxew(off); 45174212Sjhb } 45274212Sjhb 453160709Sache /* 454161286Sbrueffer * write data to the file in descending order of offset 455162890Snetchild */ 456135986Sru for (i = shnum; i-- != 0;) { 45774212Sjhb if (layoutp[i].shdr == strtabshdr) { 45874212Sjhb /* new string table */ 459162934Sariff buf = nstrtabp; 46088253Sjim } else 46174212Sjhb buf = layoutp[i].bufp; 46274212Sjhb 46374212Sjhb if (layoutp[i].shdr == &shdrshdr || 46474212Sjhb layoutp[i].shdr == symtabshdr || i >= strtabidx) { 465135986Sru if (buf == NULL) 466135986Sru goto bad; 46774212Sjhb 46874212Sjhb /* 469162890Snetchild * update the offset of section header table in elf 47074212Sjhb * header if needed. 471102011Sorion */ 47274212Sjhb if (layoutp[i].shdr == &shdrshdr && 473135986Sru ehdr.e_shoff != shdrshdr.sh_offset) { 474107175Sdcs ehdr.e_shoff = shdrshdr.sh_offset; 47574212Sjhb off = offsetof(Elf_Ehdr, e_shoff); 476285875Strasz size = sizeof(Elf_Off); 47774212Sjhb if ((size_t)xwriteatoff(fd, &ehdr.e_shoff, off, size, 47853243Sn_hibma fn) != size) 47953243Sn_hibma goto bad; 48053243Sn_hibma } 48153548Sn_hibma 48259895Sn_hibma off = xewtoh(layoutp[i].shdr->sh_offset); 48353548Sn_hibma size = xewtoh(layoutp[i].shdr->sh_size); 484209466Sbrucec if ((size_t)xwriteatoff(fd, buf, off, size, fn) != size) 48591609Salfred goto bad; 48653548Sn_hibma } 48753548Sn_hibma } 48853548Sn_hibma 48953548Sn_hibmaout: 49053548Sn_hibma if (layoutp != NULL) { 491209466Sbrucec for (i = 0; i < shnum; i++) { 49267955Sn_hibma if (layoutp[i].bufp != NULL) 493209466Sbrucec free(layoutp[i].bufp); 494209466Sbrucec } 495209466Sbrucec free(layoutp); 49655162Swpaul } 497115054Smurray free(nstrtabp); 498209466Sbrucec return (rv); 49955944Swpaul 50055429Swpaulbad: 501209466Sbrucec rv = 1; 502177990Sweongyo goto out; 503209466Sbrucec} 504209466Sbrucec 505177990Sweongyo#endif /* include this size of ELF */ 506177990Sweongyo