Fix paradynd build problem
[dyninst.git] / dyninstAPI / src / editSharedLibrary.C
1 /*
2  * Copyright (c) 1996-2004 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 /* $Id: editSharedLibrary.C,v 1.3 2005/03/22 02:52:09 legendre Exp $ */
43 #include "dyninstAPI/src/editSharedLibrary.h"
44 #include "dyninstAPI/src/util.h"
45
46
47 /*      This function will open the shared library and remove the
48         padded out bss section.  The PHT will be updated, the data segment
49         filesz will be corrected.  The Ehdr section header index will also be
50         corrected
51 */
52 bool editSharedLibrary::removeBSSfromSharedLibrary(char *libName){
53
54         elf_version(EV_CURRENT);
55         if((fd = open(libName, O_RDWR)) == -1){
56                 bpfatal("cannot open Old SO: %s\n",libName);
57                 perror(" FAIL ");
58                 return false;
59         }
60         if((oldElf = elf_begin(fd, ELF_C_RDWR, NULL)) ==NULL){
61                 bpfatal("cannot open ELF %s \n", libName);
62                 return false;
63         }
64
65         bool res = removeBSS();
66
67         elf_update(oldElf, ELF_C_WRITE);
68         elf_end(oldElf);
69         close(fd);
70
71         return res;
72 }
73
74 bool editSharedLibrary::removeBSS(){
75
76         int bssSize=0;
77         bool bssFound=false;
78         int offsetMovement=0;
79
80         Elf32_Ehdr *ehdr = elf32_getehdr(oldElf);
81         Elf32_Phdr *phdr = elf32_getphdr(oldElf);
82
83         Elf32_Shdr *shdr;
84         Elf_Scn *scn; 
85         Elf_Data *strdata, *olddata;
86
87      if (((ehdr = elf32_getehdr(oldElf)) != NULL)){ 
88
89         if((scn = elf_getscn(oldElf, ehdr->e_shstrndx)) != NULL){
90
91                 if((strdata = elf_getdata(scn, NULL)) == NULL){
92                                 bperr(" Failed obtaining .shstrtab data buffer \n");
93                                 return false;
94                         }
95                 }else{
96                         bperr(" FAILED obtaining .shstrtab scn\n");             
97                         return false;
98                 }
99         }else{
100                 bperr(" FAILED obtaining .shstrtab ehdr\n");
101                 return false;
102         }
103
104         scn = NULL;
105
106         for (int cnt = 1; (scn = elf_nextscn(oldElf, scn)); cnt++) {
107         
108                 shdr = elf32_getshdr(scn);
109                 olddata = elf_getdata(scn,NULL);
110         
111                 if( bssFound ){
112                         shdr->sh_offset -= offsetMovement;      
113
114                         while( (shdr->sh_offset % shdr->sh_addralign) != 0){
115                                 shdr->sh_offset ++;
116                                 /* offsetMovement needs decreased everytime we move a section down b/c of alignment */
117                                 offsetMovement --;
118                         }
119                 }
120
121                 if(!strcmp( (char*) strdata->d_buf + shdr->sh_name, ".bss")){
122                         bssFound =true;
123                         bssSize = shdr->sh_size;
124                         /* we will shift every succeeding section up by offsetMovement */
125                         offsetMovement = bssSize;
126
127                         //delete [] (char*)olddata->d_buf;
128
129                         /* this should get deallocated by elf when the file is closed */
130                         /* insure gives errors if i try to delete it */
131                         olddata->d_buf = NULL;
132
133
134                         shdr->sh_type = SHT_NOBITS;
135         }
136         }
137
138         /*      the section header table has moved up by offsetMovement
139                 this takes into account the size of the bss and the shifts
140                 we needed to perform for alignment purposes
141         */
142         ehdr->e_shoff -= offsetMovement;        
143
144         /* the data segment will be the second loadable section*/
145         bool foundFirstLoadable=false;
146         for(int i=0;i<ehdr->e_phnum;i++){
147                 if(!foundFirstLoadable && phdr[i].p_type == PT_LOAD){
148                         foundFirstLoadable=true;
149                 }else if(foundFirstLoadable == true && phdr[i].p_type == PT_LOAD ){
150                         
151                         phdr[i].p_filesz -= bssSize;
152                         i=ehdr->e_phnum;
153                 }
154         }
155         if( !foundFirstLoadable ){
156                 bperr(" FAILED could not find the data segment in the shared library\n");
157                 return false;
158         }
159         return true;
160 }
161
162 // vim:ts=5: