annotate dynodump/dynodump.c @ 4407:4ee73bbe4f8e

Always use boyer_moore in ASCII or Latin-1 buffers with ASCII search strings. 2007-12-26 Aidan Kehoe <kehoea@parhasard.net> * casetab.c: Extend and correct some case table documentation. * search.c (search_buffer): Correct a bug where only the first entry for a character in the case equivalence table was examined in determining if the Boyer-Moore search algorithm is appropriate. If there are case mappings outside of the charset and row of the characters specified in the search string, those case mappings can be safely ignored (and Boyer-Moore search can be used) if we know from the buffer statistics that the corresponding characters cannot occur. * search.c (boyer_moore): Assert that we haven't been passed a string with varying characters sets or rows within character sets. That's what simple_search is for. In the very rare event that a character in the search string has a canonical case mapping that is not in the same character set and row, don't try to search for the canonical character, search for some other character that is in the the desired character set and row. Assert that the case table isn't corrupt. Do not search for any character case mappings that cannot possibly occur in the buffer, given the buffer metadata about its contents.
author Aidan Kehoe <kehoea@parhasard.net>
date Wed, 26 Dec 2007 17:30:16 +0100
parents 20ae8821c23d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2 * Copyright (c) 1995 by Sun Microsystems, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 * All rights reserved.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5 * This source code is a product of Sun Microsystems, Inc. and is provided
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 * for unrestricted use provided that this legend is included on all tape
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 * media and as a part of the software program in whole or part. Users
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 * may copy or modify this source code without charge, but are not authorized
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 * to license or distribute it to anyone else except as part of a product or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10 * program developed by the user.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 * THIS PROGRAM CONTAINS SOURCE CODE COPYRIGHTED BY SUN MICROSYSTEMS, INC.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 * SUN MICROSYSTEMS, INC., MAKES NO REPRESENTATIONS ABOUT THE SUITABLITY
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 * OF SUCH SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 * EXPRESS OR IMPLIED WARRANTY OF ANY KIND. SUN MICROSYSTEMS, INC. DISCLAIMS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 * ALL WARRANTIES WITH REGARD TO SUCH SOURCE CODE, INCLUDING ALL IMPLIED
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 * NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 * FROM USE OF SUCH SOURCE CODE, REGARDLESS OF THE THEORY OF LIABILITY.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22 * This source code is provided with no support and without any obligation on
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 * the part of Sun Microsystems, Inc. to assist in its use, correction,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 * modification or enhancement.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 * SOURCE CODE OR ANY PART THEREOF.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 * Sun Microsystems, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 * 2550 Garcia Avenue
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 * Mountain View, California 94043
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 * dynodump(3x) dumps a running executable into a specified ELF file. The new
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 * file consists of the memory contents of the original file together with any
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 * heap. This heap is assigned to a new `.heap' section within the new file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 * The new file may be re-executed, and will contain any data modifications
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 * made to the original image up until the time dynodump(3x) was called.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 * The original image may have undergone relocations (performed by ld.so.1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 * prior to control being transferred to the image. These relocations will
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 * reside as the data copied from the image. To prevent subsequent executions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 * of the new image from undergoing the same relocations, any relocation entries
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 * (besides copy or jump slot relocations) are nulled out. Note that copy
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 * relocations such as required for __iob must be reinitialized each time the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 * process starts, so it is not sufficient to simply null out the .dynamic
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 * sections relocation information. The effect of this is that if the new
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 * image was bound to definitions in any shared object dependencies, then these
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 * dependencies *must* reside in the same location as when dynodump(3x) was
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 * called. Any changes to the shared object dependencies of the new image, or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 * uses of such things as LD_PRELOAD, may result in the bindings encoded in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 * image becoming invalid.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 * The following flags modify the data of the image created:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 * RTLD_SAVREL save the original relocation data. Under this option any
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 * relocation offset is reset to contain the same data as was
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 * found in the images original file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 * This option allows relocation information to be retained in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 * new image so that it may be re-executed when the new image is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 * run. This allows far greater flexibility as the new image can
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 * now take advantage of new shared objects.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 * Note. under this mechanism, any data item that undergoes
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 * relocation and is then further modified during the execution of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 * the image before dynodump(3x) is called will lose the
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
71 * modification that occurred during the applications execution.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 * N.B. The above commentary is not quite correct in the flags have been hardwired
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 * to RTLD_SAVREL.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 */
468
20ae8821c23d [xemacs-hg @ 2001-04-13 09:11:17 by michaels]
michaels
parents: 464
diff changeset
76 #pragma ident "@(#) $Id: dynodump.c,v 1.9 2001/04/13 09:11:20 michaels Exp $ - SMI"
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 #define __EXTENSIONS__ 1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 #include <sys/param.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 #include <sys/procfs.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 #include <fcntl.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 #include <stdio.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 #include <libelf.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85 #include <link.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 #include <stdlib.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 #include <string.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 #include <unistd.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 #include <errno.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 #include <malloc.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 #include "machdep.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 #include "_dynodump.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 * Generic elf error message generator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 elferr(const char * str)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 fprintf(stderr, "%s: %s\n", str, elf_errmsg(elf_errno()));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 return (1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 int dynodump (const char * file);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 dynodump(const char * file)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 Elf *ielf, *oelf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 Ehdr *iehdr, *oehdr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 Phdr *iphdr, *ophdr, *data_phdr = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 Cache *icache, *ocache, *_icache, *_ocache;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 Cache *data_cache = 0, *shstr_cache = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 Cache *heap_cache = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 Word heap_sz = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 Elf_Scn *scn;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 Shdr *shdr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 Elf_Data *data, rundata;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 Half ndx, _ndx;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 int fd, _fd;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 Addr edata, _addr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 char *istrs, *ostrs, *_ostrs, proc[16];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 const char heap[] = ".heap";
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 prstatus_t pstat;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 /* make a call to the processor specific un-init stuff */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 dynodump_uninit();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 * Obtain a file descriptor for this process,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 * for the executable and get a prstatus_t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 * structure.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 sprintf(proc, "/proc/%ld", getpid());
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 if (((_fd = open(proc, O_RDONLY, 0)) == -1) ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 ((fd = ioctl(_fd, PIOCOPENM, (void *)0)) == -1) ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 (ioctl(_fd, PIOCSTATUS, &pstat) == -1)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 fprintf(stderr, "/proc: initialization error: %s\n",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 strerror(errno));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 close(_fd);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 return (1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 close(_fd);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 * Initialize with the ELF library and make sure this is an executable
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 * ELF file we're dealing with.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 elf_version(EV_CURRENT);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 if ((ielf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 close(fd);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 return (elferr("elf_begin"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 close(fd);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 if ((elf_kind(ielf) != ELF_K_ELF) ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 ((iehdr = elf_getehdr(ielf)) == NULL) ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 (iehdr->e_type != ET_EXEC)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 fprintf(stderr, "image is not an ELF executable\n");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 elf_end(ielf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 return (1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 * Elf_elf_header(iehdr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 * Create the new output file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0777)) == -1) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 fprintf(stderr, "%s: open failed: %s\n", file,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 strerror(errno));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 elf_end(ielf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 return (1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 if ((oelf = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 elf_end(ielf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 close(fd);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 return (elferr("elf_begin"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 * Obtain the input program headers. Remember the data segments
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 * program header entry as this will be updated later to reflect the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 * new .heap sections size.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 if ((iphdr = elf_getphdr(ielf)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 return (elferr("elf_getphdr"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 for (ndx = 0, ophdr = iphdr; ndx != iehdr->e_phnum; ndx++, ophdr++) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 * Save the program header that contains the NOBITS section, or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 * the last loadable program header if no NOBITS exists.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 * A NOBITS section translates to a memory size requirement that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 * is greater than the file data it is mapped from.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 if (ophdr->p_type == PT_LOAD) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 if (ophdr->p_filesz != ophdr->p_memsz)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 data_phdr = ophdr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 else if (data_phdr) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 if (data_phdr->p_vaddr < ophdr->p_vaddr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 data_phdr = ophdr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 } else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 data_phdr = ophdr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 if (data_phdr == 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 fprintf(stderr, "no data segment found!\n");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 return (0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 * Obtain the input files section header string table.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 if ((scn = elf_getscn(ielf, iehdr->e_shstrndx)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 return (elferr("elf_getscn"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 if ((data = elf_getdata(scn, NULL)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 return (elferr("elf_getdata"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 istrs = (char *) data->d_buf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 * Construct a cache to maintain the input files section information.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 if ((icache = (Cache *) malloc(iehdr->e_shnum * sizeof (Cache))) == 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 fprintf(stderr, "malloc failed: %s\n", strerror(errno));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 return (1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 _icache = icache;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 _icache++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 * Traverse each section from the input file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 for (ndx = 1, scn = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 (_icache->c_scn = elf_nextscn(ielf, scn));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 ndx++, scn = _icache->c_scn, _icache++) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 if ((_icache->c_shdr = shdr = elf_getshdr(_icache->c_scn)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 return (elferr("elf_getshdr"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 if ((_icache->c_data = elf_getdata(_icache->c_scn, NULL)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 return (elferr("elf_getdata"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 _icache->c_name = istrs + (size_t)(shdr->sh_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 * For each section that has a virtual address reestablish the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 * data buffer to point to the memory image.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 * if (shdr->sh_addr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 * _icache->c_data->d_buf = (void *)shdr->sh_addr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 * Remember the last section of the data segment, the new .heap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 * section will be added after this section.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 * If we already have one, then set data_cache to the previous
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 * section and set heap_cache to this one.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 if ((shdr->sh_addr + shdr->sh_size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 == (data_phdr->p_vaddr + data_phdr->p_memsz)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 if (strcmp(_icache->c_name, heap) == 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 #ifdef DEBUG
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 printf("Found a previous .heap section\n");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 data_cache = _icache - 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 heap_cache = _icache;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 heap_sz = shdr->sh_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 } else {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 data_cache = _icache;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 * Remember the section header string table as this will be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 * rewritten with the new .heap name.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 if ((shdr->sh_type == SHT_STRTAB) &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 ((strcmp(_icache->c_name, ".shstrtab")) == 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 shstr_cache = _icache;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 if (data_cache == 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 fprintf(stderr, "final data section not found!\n");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 return (0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 * Determine the new .heap section to create.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 rundata.d_buf = (void *)(data_cache->c_shdr->sh_addr +
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 data_cache->c_shdr->sh_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 rundata.d_size = (int)sbrk(0) - (int)rundata.d_buf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 rundata.d_type = ELF_T_BYTE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 rundata.d_off = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 rundata.d_align = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 rundata.d_version = EV_CURRENT;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 * From the new data buffer determine the new value for _end and _edata.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 * This will also be used to update the data segment program header.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 * If we had a .heap section, then its size is part of the program
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 * headers notion of data size. Because we're only going to output one
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 * heap section (ignoring the one in the running binary) we need to
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
304 * subtract the size of that which we're ignoring.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 if (heap_cache) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 edata = S_ROUND((data_phdr->p_vaddr
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 + data_phdr->p_memsz
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 - heap_sz), rundata.d_align) + rundata.d_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 } else {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 edata = S_ROUND((data_phdr->p_vaddr + data_phdr->p_memsz),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 rundata.d_align) + rundata.d_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 * We're now ready to construct the new elf image.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 * Obtain a new elf header and initialize it with any basic information
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 * that isn't calculated as part of elf_update(). Bump the section
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 * header string table index to account for the .heap section we'll be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 * adding.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 if ((oehdr = elf_newehdr(oelf)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 return (elferr("elf_newehdr"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 oehdr->e_entry = iehdr->e_entry;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 oehdr->e_machine = iehdr->e_machine;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 oehdr->e_type = iehdr->e_type;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 oehdr->e_flags = iehdr->e_flags;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 * If we already have a heap section, we don't need any adjustment
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 if (heap_cache)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 oehdr->e_shstrndx = iehdr->e_shstrndx;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 oehdr->e_shstrndx = iehdr->e_shstrndx + 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 #ifdef DEBUG
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 printf("iehdr->e_flags = %x\n", iehdr->e_flags);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 printf("iehdr->e_entry = %x\n", iehdr->e_entry);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 printf("iehdr->e_shstrndx= %d\n", iehdr->e_shstrndx);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 printf("iehdr->e_machine = %d\n", iehdr->e_machine);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 printf("iehdr->e_type = 0x%x\n", iehdr->e_type);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 printf("oehdr->e_machine = %d\n", oehdr->e_machine);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 printf("oehdr->e_type = 0x%x\n", oehdr->e_type);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 * Obtain a new set of program headers. Initialize these with the same
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 * information as the input program headers and update the data segment
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 * to reflect the new .heap section.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 if ((ophdr = elf_newphdr(oelf, iehdr->e_phnum)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 return (elferr("elf_newphdr"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 for (ndx = 0; ndx != iehdr->e_phnum; ndx++, iphdr++, ophdr++) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 *ophdr = *iphdr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 if (data_phdr == iphdr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 ophdr->p_filesz = ophdr->p_memsz = edata - ophdr->p_vaddr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 * Obtain a new set of sections.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 _icache = icache;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 _icache++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 for (ndx = 1; ndx != iehdr->e_shnum; ndx++, _icache++) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 * Skip the heap section of the running executable
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 if (_icache == heap_cache)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 continue;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 * Create a matching section header in the output file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 if ((scn = elf_newscn(oelf)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 return (elferr("elf_newscn"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 if ((shdr = elf_getshdr(scn)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 return (elferr("elf_getshdr"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 *shdr = *_icache->c_shdr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 * Create a matching data buffer for this section.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 if ((data = elf_newdata(scn)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 return (elferr("elf_newdata"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 *data = *_icache->c_data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 * For each section that has a virtual address reestablish the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 * data buffer to point to the memory image. Note, we skip
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 * the plt section.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 if ((shdr->sh_addr) && (!((shdr->sh_type == SHT_PROGBITS)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 && (strcmp(_icache->c_name, ".plt") == 0))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 data->d_buf = (void *)shdr->sh_addr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 * Update any NOBITS section to indicate that it now contains
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 * data.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 if (shdr->sh_type == SHT_NOBITS)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 shdr->sh_type = SHT_PROGBITS;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 * Add the new .heap section after the last section of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 * present data segment. If we had a heap section, then
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 * this is the section preceding it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 if (data_cache == _icache) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 if ((scn = elf_newscn(oelf)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 return (elferr("elf_newscn"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 if ((shdr = elf_getshdr(scn)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414 return (elferr("elf_getshdr"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
415 shdr->sh_type = SHT_PROGBITS;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 shdr->sh_flags = SHF_ALLOC | SHF_WRITE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418 if ((data = elf_newdata(scn)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419 return (elferr("elf_newdata"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 *data = rundata;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 * Update the section header string table size to reflect the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 * new section name (only if we didn't already have a heap).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 if (!heap_cache) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 if (shstr_cache && (shstr_cache == _icache)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 data->d_size += sizeof (heap);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 * Write out the new image, and obtain a new elf descriptor that will
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 * allow us to write to the new image.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 if (elf_update(oelf, ELF_C_WRITE) == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439 return (elferr("elf_update"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 elf_end(oelf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 if ((oelf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 return (elferr("elf_begin"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 if ((oehdr = elf_getehdr(oelf)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 return (elferr("elf_getehdr"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447 * Obtain the output files section header string table.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 if ((scn = elf_getscn(oelf, oehdr->e_shstrndx)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 return (elferr("elf_getscn"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 if ((data = elf_getdata(scn, NULL)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 return (elferr("elf_getdata"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 ostrs = _ostrs = (char *) data->d_buf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 *_ostrs++ = '\0';
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 * Construct a cache to maintain the output files section information.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 if ((ocache = (Cache *)malloc(oehdr->e_shnum * sizeof (Cache))) == 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 fprintf(stderr, "malloc failed: %s\n", strerror(errno));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 return (1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 _ocache = ocache;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 _ocache++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 _icache = icache;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 _icache++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 * Traverse each section from the input file rebuilding the section
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 * header string table as we go.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 _ndx = _addr = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 for (ndx = 1, scn = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 (_ocache->c_scn = elf_nextscn(oelf, scn));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 ndx++, scn = _ocache->c_scn, _ocache++, _icache++) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 const char *strs;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 if (_icache == heap_cache) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 #ifdef DEBUG
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 printf("ignoring .heap section in input\n");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 _icache++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 if ((_ocache->c_shdr = shdr =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 elf_getshdr(_ocache->c_scn)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488 return (elferr("elf_getshdr"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 if ((_ocache->c_data =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 elf_getdata(_ocache->c_scn, NULL)) == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 return (elferr("elf_getdata"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 * If were inserting the new .heap section, insert the new
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495 * section name and initialize its virtual address.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 if (_addr) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 strs = heap;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 shdr->sh_addr = S_ROUND(_addr, shdr->sh_addralign);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 _addr = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 } else {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 strs = istrs + (size_t)(_icache->c_shdr->sh_name);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 strcpy(_ostrs, strs);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 shdr->sh_name = _ostrs - ostrs;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 _ocache->c_name = _ostrs;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 _ostrs += strlen(strs) + 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 * If we've inserted a new section any later section may need
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 * their sh_link fields updated.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 * If we already had a heap section, then this is not required.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 if (!heap_cache) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 if (_ndx) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 if (_ocache->c_shdr->sh_link >= _ndx)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 _ocache->c_shdr->sh_link++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 * If this is the last section of the original data segment
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 * determine sufficient information to initialize the new .heap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 * section which will be obtained next.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 if (data_cache == _icache) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 _ndx = ndx + 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 _addr = shdr->sh_addr + shdr->sh_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 _icache--;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 data_cache = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 * Now that we have a complete description of the new image update any
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 * sections that are required.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539 * o update the value of _edata and _end.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 * o reset any relocation entries if necessary.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 _ocache = &ocache[1];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 _icache = &icache[1];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 for (ndx = 1; ndx < oehdr->e_shnum; ndx++, _ocache++, _icache++) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546 if ((_ocache->c_shdr->sh_type == SHT_SYMTAB) ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 (_ocache->c_shdr->sh_type == SHT_DYNSYM))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548 update_sym(ocache, _ocache, edata);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
549
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550 if (_ocache->c_shdr->sh_type == M_REL_SHT_TYPE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551 update_reloc(ocache, _ocache, icache, _icache, oehdr->e_shnum);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554 if (elf_update(oelf, ELF_C_WRITE) == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 return (elferr("elf_update"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 elf_end(oelf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558 elf_end(ielf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 return (0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560 }