modified: common/CMakeLists.txt
[dyninst.git] / dyninstAPI / src / linux-aarch64.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #warning "This file is not implemented yet!"
32
33 #include <string>
34 #include <dlfcn.h>
35
36 #include "dyninstAPI/src/linux-aarch64.h"
37 #include "dyninstAPI/src/addressSpace.h"
38 #include "dyninstAPI/src/dynProcess.h"
39 #include "dyninstAPI/src/frame.h"
40 #include "dyninstAPI/src/debug.h"
41 #include "dyninstAPI/src/mapped_object.h"
42 #include "dyninstAPI/src/inst-aarch64.h"
43 #include "dyninstAPI/src/baseTramp.h"
44 #include "dyninstAPI/src/registerSpace.h"
45 #include "dyninstAPI/src/function.h"
46
47 #define DLOPEN_MODE (RTLD_NOW | RTLD_GLOBAL)
48
49 const char DL_OPEN_FUNC_EXPORTED[] = "dlopen";
50 const char DL_OPEN_FUNC_INTERNAL[] = "_dl_open";
51 const char DL_OPEN_FUNC_NAME[] = "do_dlopen";
52 const char DL_OPEN_LIBC_FUNC_EXPORTED[] = "__libc_dlopen_mode";
53
54 Address PCProcess::getLibcStartMainParam(PCThread *) {
55     assert(!"This function is unimplemented");
56     return 0;
57 }
58
59 Address PCProcess::getTOCoffsetInfo(Address dest) {
60     if ( getAddressWidth() == 4 ) return 0;
61
62     // We have an address, and want to find the module the addr is
63     // contained in. Given the probabilities, we (probably) want
64     // the module dyninst_rt is contained in.
65     // I think this is the right func to use
66
67     // Find out which object we're in (by addr).
68     mapped_object *mobj = findObject(dest);
69
70     // Very odd case if this is not defined.
71     assert(mobj);
72     Address TOCOffset = mobj->parse_img()->getObject()->getTOCoffset();
73     
74     if (!TOCOffset)
75        return 0;
76     return TOCOffset + mobj->dataBase();
77 }
78
79 Address PCProcess::getTOCoffsetInfo(func_instance *func) {
80     if ( getAddressWidth() == 4 ) return 0;
81
82     mapped_object *mobj = func->obj();
83
84     return mobj->parse_img()->getObject()->getTOCoffset() + mobj->dataBase();
85 }
86
87 bool PCProcess::getOPDFunctionAddr(Address &addr) {
88     bool result = true;
89     if( getAddressWidth() == 8 ) {
90         Address resultAddr = 0;
91         if( !readDataSpace((const void *)addr, getAddressWidth(),
92                     (void *)&resultAddr, false) ) 
93         {
94             result = false;
95         }else{
96             addr = resultAddr;
97        }
98     }
99     return result;
100 }
101
102 AstNodePtr PCProcess::createUnprotectStackAST() {
103     // This is not necessary on power
104     return AstNode::nullNode();
105 }
106
107 bool Frame::setPC(Address newpc) {
108    Address pcAddr = getPClocation();
109    if (!pcAddr)
110    {
111        //fprintf(stderr, "[%s:%u] - Frame::setPC aborted", __FILE__, __LINE__);
112       return false;
113    }
114
115    //fprintf(stderr, "[%s:%u] - Frame::setPC setting %x to %x",
116    //__FILE__, __LINE__, pcAddr_, newpc);
117    if (getProc()->getAddressWidth() == sizeof(uint64_t)) {
118       uint64_t newpc64 = newpc;
119       if (!getProc()->writeDataSpace((void*)pcAddr, sizeof(newpc64), &newpc64))
120          return false;
121       sw_frame_.setRA(newpc64);
122    }
123    else {
124       uint32_t newpc32 = newpc;
125       if (!getProc()->writeDataSpace((void*)pcAddr, sizeof(newpc32), &newpc32))
126          return false;
127       sw_frame_.setRA(newpc32);
128    }
129
130    return true;
131 }
132
133 bool AddressSpace::getDyninstRTLibName() {
134 //full path to libdyninstAPI_RT (used an _m32 suffix for 32-bit version)
135     startup_printf("dyninstRT_name: %s\n", dyninstRT_name.c_str());
136     if (dyninstRT_name.length() == 0) {
137         // Get env variable
138         if (getenv("DYNINSTAPI_RT_LIB") != NULL) {
139             dyninstRT_name = getenv("DYNINSTAPI_RT_LIB");
140         }
141         else {
142             std::string msg = std::string("Environment variable ") +
143                 std::string("DYNINSTAPI_RT_LIB") +
144                std::string(" has not been defined");
145             showErrorCallback(101, msg);
146             return false;
147         }
148     }
149
150     // Automatically choose 32-bit library if necessary.
151     const char *modifier = "";
152     const char *name = dyninstRT_name.c_str();
153
154     const char *split = P_strrchr(name, '/');
155     if ( !split ) split = name;
156     split = P_strchr(split, '.');
157     if ( !split || P_strlen(split) <= 1 ) {
158         // We should probably print some error here.
159         // Then, of course, the user will find out soon enough.
160         startup_printf("Invalid Dyninst RT lib name: %s\n", 
161                 dyninstRT_name.c_str());
162         return false;
163     }
164
165     if (getAddressWidth() == 4 &&
166         (sizeof(void *) == 8)) {
167        // Need _m32...
168        if (P_strstr(name, "_m32") == NULL) {
169           modifier = "_m32";
170        }
171     }
172
173     const char *suffix = split;
174     if( getAOut()->isStaticExec() ) {
175         suffix = ".a";
176     }else{
177         if( P_strncmp(suffix, ".a", 2) == 0 ) {
178             // This will be incorrect if the RT library's version changes
179             suffix = ".so";
180         }
181     }
182
183     dyninstRT_name = std::string(name, split - name) +
184                      std::string(modifier) +
185                      std::string(suffix);
186
187     startup_printf("Dyninst RT Library name set to '%s'\n",
188             dyninstRT_name.c_str());
189
190     // Check to see if the library given exists.
191     if (access(dyninstRT_name.c_str(), R_OK)) {
192         std::string msg = std::string("Runtime library ") + dyninstRT_name
193         + std::string(" does not exist or cannot be accessed!");
194         showErrorCallback(101, msg);
195         cerr << msg << endl;
196         return false;
197     }
198     return true;
199 }
200
201 // floor of inferior malloc address range within a single branch of x
202 // for 32-bit ELF PowerPC mutatees
203 Address region_lo(const Address x) {
204    const Address floor = getpagesize();
205
206    assert(x >= floor);
207
208    if ((x > floor) && (x - floor > getMaxBranch()))
209       return x - getMaxBranch();
210
211    return floor;
212 }
213
214
215 // floor of inferior malloc address range within a single branch of x
216 // for 64-bit ELF PowerPC mutatees
217 Address region_lo_64(const Address x) {
218    const Address floor = getpagesize();
219
220    assert(x >= floor);
221
222    if ((x > floor) && (x - floor > getMaxBranch()))
223       return x - getMaxBranch();
224
225    return floor;
226 }
227
228
229 // ceiling of inferior malloc address range within a single branch of x
230 // for 32-bit ELF PowerPC mutatees
231 Address region_hi(const Address x) {
232    const Address ceiling = ~(Address)0 & 0xffffffff;
233
234    assert(x < ceiling);
235
236    if ((x < ceiling) && (ceiling - x > getMaxBranch()))
237       return x + getMaxBranch();
238
239    return ceiling;
240 }
241
242
243 // ceiling of inferior malloc address range within a single branch of x
244 // for 64-bit ELF PowerPC mutatees
245 Address region_hi_64(const Address x) {
246    const Address ceiling = ~(Address)0;
247
248    assert(x < ceiling);
249
250    if ((x < ceiling) && (ceiling - x > getMaxBranch()))
251       return x + getMaxBranch();
252
253    return ceiling;
254 }