00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "common/h/addrtranslate.h"
00032 #include "common/h/headers.h"
00033 #include "common/h/pathName.h"
00034
00035 #include "symtabAPI/h/Symtab.h"
00036 #include "symtabAPI/h/Archive.h"
00037
00038 #include <sys/procfs.h>
00039 #include <string.h>
00040 #include <string>
00041 #include <vector>
00042 #include <map>
00043
00044 namespace Dyninst {
00045
00046 class AddressTranslateAIX : public AddressTranslate
00047 {
00048 public:
00049 AddressTranslateAIX(SymbolReaderFactory *fact_);
00050 AddressTranslateAIX(PID pid, SymbolReaderFactory *fact_);
00051
00052 virtual bool refresh();
00053 virtual ~AddressTranslateAIX();
00054 Address getLibraryTrapAddrSysV();
00055 };
00056
00057 class LoadedLibAIX : public LoadedLib {
00058 protected:
00059 string object;
00060
00061 mutable Address real_codeBase;
00062 mutable Address real_dataBase;
00063 mutable Address imageOffset;
00064 mutable Address dataOffset;
00065 mutable bool reals_set;
00066 void setReals() const;
00067 public:
00068 LoadedLibAIX(string name, Address load_addr, string object);
00069
00070 virtual ~LoadedLibAIX();
00071
00072 virtual Address offToAddress(Offset off);
00073 virtual Offset addrToOffset(Address addr);
00074
00075 virtual Address getCodeLoadAddr() const;
00076 virtual Address getDataLoadAddr() const;
00077 virtual void getOutputs(string &filename, Address &code, Address &data);
00078 };
00079
00080 static int open_map_fd(PID pid)
00081 {
00082 char file[64];
00083 snprintf(file, 64, "/proc/%d/map", pid);
00084 int fd = P_open(file, O_RDONLY, pid);
00085 return fd;
00086 }
00087
00088 bool AddressTranslateAIX::refresh()
00089 {
00090 unsigned iter = 0;
00091 bool is_aout = true;
00092 int map_fd = -1;
00093 int result;
00094 if (!pid)
00095 return true;
00096
00097 for (unsigned i=0; i<libs.size(); i++) {
00098 if (libs[i])
00099 delete libs[i];
00100 }
00101 libs.clear();
00102
00103 map_fd = open_map_fd(pid);
00104 if (map_fd == -1)
00105 return false;
00106
00107 prmap_t mapEntry;
00108
00109 #if defined(DEBUG_PRINT)
00110 for (;;) {
00111 result = pread(map_fd, &mapEntry, sizeof(prmap_t), iter * sizeof(prmap_t));
00112 if (result != sizeof(prmap_t))
00113 break;
00114 if (mapEntry.pr_size == 0)
00115 break;
00116
00117 char buf[512];
00118 if (mapEntry.pr_pathoff) {
00119 pread(map_fd, buf, 512, mapEntry.pr_pathoff);
00120 }
00121
00122 printf("%lu\n"
00123 "\taddr = %llx +%llu\n"
00124 "\tmapname = %s\n"
00125 "\toffset = %llu, flags = %d\n"
00126 "\tpr_pathoff = %d (%s)\n"
00127 "\tobject = %s\n"
00128 "\talias = %llx, gp = %llx\n",
00129 iter * sizeof(prmap_t),
00130 mapEntry.pr_vaddr, mapEntry.pr_size,
00131 mapEntry.pr_mapname,
00132 mapEntry.pr_off, mapEntry.pr_mflags,
00133 mapEntry.pr_pathoff, mapEntry.pr_pathoff ? buf : "NONE",
00134 mapEntry.pr_pathoff ? buf + strlen(buf) + 1 : "NONE",
00135 mapEntry.pr_alias, mapEntry.pr_gp);
00136 if (mapEntry.pr_pathoff) {
00137 string filename = buf;
00138 string object_name = buf + strlen(buf) + 1;
00139 LoadedLib *ll = new LoadedLibAIX(filename, 0, object_name);
00140 Symtab *s = ll->getSymtab();
00141 printf("\timageOffset = %ld, length = %lu\n"
00142 "\tdataOffset = %ld, length = %lu\n",
00143 s->imageOffset(), s->imageLength(),
00144 s->dataOffset(), s->dataLength());
00145 }
00146
00147 printf("\n");
00148 iter++;
00149 }
00150 #endif
00151
00152 iter = 0;
00153
00154 for (;;) {
00155 result = pread(map_fd, &mapEntry, sizeof(prmap_t), iter * sizeof(prmap_t));
00156 if (result != sizeof(prmap_t))
00157 break;
00158 if (mapEntry.pr_size == 0)
00159 break;
00160
00161 string filename;
00162 string object_name;
00163 if (mapEntry.pr_pathoff) {
00164 char buf[512];
00165 pread(map_fd, buf, 256, mapEntry.pr_pathoff);
00166 filename = resolve_file_path(buf);
00167 object_name = buf + strlen(buf) + 1;
00168 }
00169 else {
00170 filename = resolve_file_path(mapEntry.pr_mapname);
00171 }
00172
00173 is_aout = false;
00174
00175 LoadedLib *ll = new LoadedLibAIX(filename, (unsigned long)mapEntry.pr_vaddr, object_name);
00176
00177 iter++;
00178 ll->add_mapped_region((unsigned long)mapEntry.pr_vaddr, mapEntry.pr_size);
00179 libs.push_back(ll);
00180
00181 prmap_t next;
00182 result = pread(map_fd, &next, sizeof(prmap_t), iter * sizeof(prmap_t));
00183 if (result != sizeof(prmap_t))
00184 break;
00185 if (strcmp(mapEntry.pr_mapname, next.pr_mapname))
00186 continue;
00187
00188 iter++;
00189 ll->add_mapped_region((unsigned long)next.pr_vaddr, next.pr_size);
00190 ll->setDataLoadAddr((unsigned long)next.pr_vaddr);
00191 }
00192
00193 P_close(map_fd);
00194 return true;
00195 }
00196
00197 AddressTranslate *AddressTranslate::createAddressTranslator(PID pid_,
00198 ProcessReader *,
00199 SymbolReaderFactory *fact,
00200 PROC_HANDLE,
00201 std::string,
00202 Address)
00203 {
00204 AddressTranslate *at = new AddressTranslateAIX(pid_, fact);
00205
00206 if (!at) {
00207 return NULL;
00208 }
00209 else if (at->creation_error) {
00210 delete at;
00211 return NULL;
00212 }
00213 return at;
00214 }
00215
00216 AddressTranslate *AddressTranslate::createAddressTranslator(ProcessReader *, SymbolReaderFactory *fact, std::string exename, Address)
00217 {
00218 return createAddressTranslator(getpid(), NULL, fact);
00219 }
00220
00221 AddressTranslateAIX::AddressTranslateAIX(SymbolReaderFactory *fact)
00222 : AddressTranslate(0)
00223 {
00224 symfactory = fact;
00225 }
00226
00227 AddressTranslateAIX::AddressTranslateAIX(PID pid, SymbolReaderFactory *fact)
00228 : AddressTranslate(pid)
00229 {
00230 symfactory = fact;
00231 refresh();
00232 }
00233
00234 AddressTranslateAIX::~AddressTranslateAIX()
00235 {
00236 }
00237
00238 vector< pair<Address, unsigned long> > *LoadedLib::getMappedRegions()
00239 {
00240 return &mapped_regions;
00241 }
00242
00243 LoadedLibAIX::LoadedLibAIX(string name, Address load_addr, string obj)
00244 : LoadedLib(name, load_addr),
00245 object(obj),
00246 real_codeBase(0),
00247 real_dataBase(0),
00248 imageOffset(0),
00249 dataOffset(0),
00250 reals_set(false)
00251 {
00252 }
00253
00254 LoadedLibAIX::~LoadedLibAIX()
00255 {
00256 }
00257
00258 void LoadedLibAIX::setReals() const
00259 {
00260 if (reals_set)
00261 return;
00262
00263 SymReader *sreader = symreader_factory->openSymbolReader(name);
00264 imageOffset = sreader->imageOffset();
00265 dataOffset = sreader->dataOffset();
00266 real_codeBase = 0;
00267 real_dataBase = 0;
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 reals_set = true;
00292 }
00293
00294 Address LoadedLibAIX::offToAddress(Offset off)
00295 {
00296 setReals();
00297
00298 Address addr = off;
00299
00300 if ((imageOffset < dataOffset && addr >= imageOffset && addr < dataOffset) ||
00301 (imageOffset > dataOffset && addr > imageOffset))
00302 {
00303 return addr + real_codeBase;
00304 }
00305 else
00306 {
00307 return addr + real_dataBase;
00308 }
00309 }
00310
00311 Offset LoadedLibAIX::addrToOffset(Address addr)
00312 {
00313 setReals();
00314
00315 if (addr >= mapped_regions[0].first &&
00316 addr < mapped_regions[0].first + mapped_regions[0].second)
00317 return addr - real_codeBase;
00318 else
00319 return addr - real_dataBase;
00320 }
00321
00322 Address LoadedLibAIX::getCodeLoadAddr() const
00323 {
00324 setReals();
00325 return real_codeBase;
00326 }
00327
00328 Address LoadedLibAIX::getDataLoadAddr() const
00329 {
00330 setReals();
00331 return real_dataBase;
00332 }
00333
00334 void LoadedLibAIX::getOutputs(string &filename, Address &code, Address &data)
00335 {
00336 if (object.length())
00337 filename = name + ":" + object;
00338 else
00339 filename = name;
00340 code = load_addr;
00341 data = data_load_addr;
00342 }
00343
00344 Address AddressTranslateAIX::getLibraryTrapAddrSysV()
00345 {
00346 return 0x0;
00347 }
00348
00349 }