00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "errno.h"
00022 #include <stdlib.h>
00023
00024 #include "htendian.h"
00025 #include "htle.h"
00026 #include "htlehead.h"
00027 #include "htleimg.h"
00028 #include "htleobj.h"
00029 #include "htleent.h"
00030 #include "htlepage.h"
00031 #include "htlevxd.h"
00032 #include "htiobox.h"
00033 #include "htnewexe.h"
00034 #include "lestruct.h"
00035 #include "log.h"
00036 #include "tools.h"
00037
00038 #define LE_SEG_ADDR(i) (LE_shared->objmap.header[(i)].page_map_index-1) *\
00039 LE_shared->hdr.pagesize + LE_BASE_ADDR
00040
00041 static format_viewer_if *htle_ifs[] = {
00042 &htleheader_if,
00043 &htlevxd_if,
00044 &htlepagemaps_if,
00045 &htleobjects_if,
00046 &htleentrypoints_if,
00047 &htleimage_if,
00048 0
00049 };
00050
00051 static ht_view *htle_init(bounds *b, ht_streamfile *file, ht_format_group *format_group)
00052 {
00053 byte lemagic[2];
00054 FILEOFS h=get_newexe_header_ofs(file);
00055 file->seek(h);
00056 file->read(lemagic, 2);
00057 if ((lemagic[0]!=LE_MAGIC0) || (lemagic[1]!=LE_MAGIC1)) return 0;
00058
00059 ht_le *g=new ht_le();
00060 g->init(b, file, htle_ifs, format_group, h);
00061 return g;
00062 }
00063
00064 format_viewer_if htle_if = {
00065 htle_init,
00066 0
00067 };
00068
00069 void ht_le::init(bounds *b, ht_streamfile *file, format_viewer_if **ifs, ht_format_group *format_group, FILEOFS h)
00070 {
00071 ht_format_group::init(b, VO_BROWSABLE | VO_SELECTABLE | VO_RESIZE, DESC_LE, file, false, true, 0, format_group);
00072 VIEW_DEBUG_NAME("ht_le");
00073
00074 LOG("%s: LE: found header at %08x", file->get_filename(), h);
00075 ht_le_shared_data *le_shared = (ht_le_shared_data*)malloc(sizeof(ht_le_shared_data));
00076 shared_data = le_shared;
00077 le_shared->v_header = NULL;
00078 le_shared->v_objects = NULL;
00079 le_shared->v_pagemaps = NULL;
00080 le_shared->v_image = NULL;
00081 le_shared->v_le_vxd = NULL;
00082 le_shared->hdr_ofs = h;
00083 le_shared->linear_file = NULL;
00084 le_shared->reloc_file = NULL;
00085 le_shared->best_entrypoint = LE_ADDR_INVALID;
00086
00087
00088 le_shared->byteorder = little_endian;
00089
00090
00091 file->seek(h);
00092 file->read(&le_shared->hdr, sizeof le_shared->hdr);
00093 create_host_struct(&le_shared->hdr, LE_HEADER_struct, le_shared->byteorder);
00094
00095 le_shared->is_vxd = (le_shared->hdr.winresoff) ||
00096 (le_shared->hdr.winreslen) ||
00097 (le_shared->hdr.devid) ||
00098 (le_shared->hdr.ddkver);
00099
00100 read_pagemap();
00101 read_objects();
00102
00103 ht_le_page_file *lfile = new ht_le_page_file();
00104 lfile->init(file, false, &le_shared->pagemap, le_shared->pagemap.count,
00105 le_shared->hdr.pagesize);
00106 le_shared->linear_file = lfile;
00107
00108 do_fixups();
00109 check_vxd();
00110
00111 ht_format_group::init_ifs(ifs);
00112 }
00113
00114 void ht_le::done()
00115 {
00116 ht_format_group::done();
00117
00118 ht_le_shared_data *le_shared=(ht_le_shared_data*)shared_data;
00119
00120 if (le_shared->objmap.header) free(le_shared->objmap.header);
00121 if (le_shared->objmap.vsize) free(le_shared->objmap.vsize);
00122 if (le_shared->objmap.psize) free(le_shared->objmap.psize);
00123
00124 if (le_shared->pagemap.offset) free(le_shared->pagemap.offset);
00125 if (le_shared->pagemap.vsize) free(le_shared->pagemap.vsize);
00126 if (le_shared->pagemap.psize) free(le_shared->pagemap.psize);
00127
00128 if (le_shared->linear_file) {
00129 le_shared->linear_file->done();
00130 delete le_shared->linear_file;
00131 }
00132
00133 if (le_shared->reloc_file) {
00134 le_shared->reloc_file->done();
00135 delete le_shared->reloc_file;
00136 }
00137
00138 free(le_shared);
00139 }
00140
00141 void ht_le::do_fixups()
00142 {
00143 ht_le_shared_data *le_shared = (ht_le_shared_data*)shared_data;
00144 FILEOFS h = le_shared->hdr_ofs;
00145
00146 uint32 *page_fixup_ofs = (uint32*)malloc(sizeof (uint32) * (le_shared->hdr.pagecnt+1));
00147 uint32 *page_fixup_size = (uint32*)malloc(sizeof (uint32) * (le_shared->hdr.pagecnt));
00148
00149 file->seek(h+le_shared->hdr.fpagetab);
00150 for (UINT i=0; i<le_shared->hdr.pagecnt+1; i++) {
00151 char buf[4];
00152 file->read(buf, 4);
00153 uint32 ofs = create_host_int(buf, 4, little_endian);
00154 page_fixup_ofs[i] = ofs;
00155 }
00156
00157 for (UINT i=0; i<le_shared->hdr.pagecnt; i++) {
00158 page_fixup_size[i] = page_fixup_ofs[i+1] - page_fixup_ofs[i];
00159 }
00160
00161 ht_le_reloc_file *rfile = new ht_le_reloc_file();
00162 rfile->init(le_shared->linear_file, false, le_shared);
00163
00164 le_shared->reloc_file = rfile;
00165
00166 UINT error_count = 0;
00167
00168 for (UINT i=0; i<le_shared->hdr.pagecnt; i++) {
00169
00170 uint32 size = page_fixup_size[i];
00171 UINT obj_ofs = i * le_shared->hdr.pagesize;
00172
00173 file->seek(h+le_shared->hdr.frectab+page_fixup_ofs[i]);
00174 bool error = false;
00175 while (size>0 && !error) {
00176
00177 LE_FIXUP f;
00178 if (sizeof f > size) { error = true; break; }
00179 size -= sizeof f;
00180 file->read(&f, sizeof f);
00181 create_host_struct(&f, LE_FIXUP_struct, le_shared->byteorder);
00182
00183 if ((f.reloc_type != 0) && (f.reloc_type != 16)) {
00184 error = true;
00185 break;
00186 }
00187
00188
00189 switch (f.address_type & LE_FIXUP_ADDR_TYPE_MASK) {
00190 case LE_FIXUP_ADDR_TYPE_0_8:
00191 case LE_FIXUP_ADDR_TYPE_16_0:
00192 case LE_FIXUP_ADDR_TYPE_16_16:
00193 case LE_FIXUP_ADDR_TYPE_0_16:
00194 case LE_FIXUP_ADDR_TYPE_16_32:
00195 case LE_FIXUP_ADDR_TYPE_0_32:
00196 case LE_FIXUP_ADDR_TYPE_REL32:
00197 break;
00198 default:
00199 error = true;
00200 break;
00201 }
00202 if (error) break;
00203
00204 UINT multi_count = 0;
00205 uint16 src_ofs;
00206 bool multi_ofs = (f.address_type & LE_FIXUP_ADDR_MULTIPLE);
00207 if (multi_ofs) {
00208
00209 char buf[1];
00210 if (sizeof buf > size) { error = true; break; }
00211 size -= sizeof buf;
00212 file->read(buf, sizeof buf);
00213 multi_count = create_host_int(buf, 1, little_endian);
00214 } else {
00215
00216 char buf[2];
00217 if (sizeof buf > size) { error = true; break; }
00218 size -= sizeof buf;
00219 file->read(buf, sizeof buf);
00220 src_ofs = create_host_int(buf, 2, little_endian);
00221 }
00222
00223 switch (f.reloc_type & LE_FIXUP_RELOC_TYPE_MASK) {
00224 case LE_FIXUP_RELOC_TYPE_INTERNAL:
00225 uint16 target_seg;
00226 uint32 target_ofs;
00227 if (f.reloc_type & LE_FIXUP_RELOC_TARGET32) {
00228 LE_FIXUP_INTERNAL32 x;
00229 if (sizeof x > size) { error = true; break; }
00230 size -= sizeof x;
00231 file->read(&x, sizeof x);
00232 create_host_struct(&x, LE_FIXUP_INTERNAL32_struct, le_shared->byteorder);
00233 target_seg = x.seg-1;
00234 target_ofs = x.ofs;
00235 } else {
00236 LE_FIXUP_INTERNAL16 x;
00237 if (sizeof x > size) { error = true; break; }
00238 size -= sizeof x;
00239 file->read(&x, sizeof x);
00240 create_host_struct(&x, LE_FIXUP_INTERNAL16_struct, le_shared->byteorder);
00241 target_seg = x.seg-1;
00242 target_ofs = x.ofs;
00243 }
00244
00245 if (multi_ofs) {
00246 for (UINT j=0; j<multi_count; j++) {
00247 char buf[2];
00248 if (sizeof buf > size) { error = true; break; }
00249 size -= sizeof buf;
00250 file->read(buf, sizeof buf);
00251 src_ofs = create_host_int(buf, sizeof buf, little_endian);
00252 rfile->insert_reloc(obj_ofs + src_ofs, new ht_le_reloc_entry(obj_ofs + src_ofs, target_seg, LE_MAKE_ADDR(le_shared, target_seg, target_ofs), f.address_type, f.reloc_type));
00253 }
00254 } else {
00255 rfile->insert_reloc(obj_ofs + src_ofs, new ht_le_reloc_entry(obj_ofs + src_ofs, target_seg, LE_MAKE_ADDR(le_shared, target_seg, target_ofs), f.address_type, f.reloc_type));
00256 }
00257 break;
00258 case LE_FIXUP_RELOC_TYPE_IMPORT_ORD:
00259 error = true;
00260 break;
00261 case LE_FIXUP_RELOC_TYPE_IMPORT_NAME:
00262 error = true;
00263 break;
00264 case LE_FIXUP_RELOC_TYPE_OSFIXUP:
00265 error = true;
00266 break;
00267 }
00268 }
00269 if (error) error_count++;
00270 }
00271
00272 free(page_fixup_ofs);
00273 free(page_fixup_size);
00274
00275 if (error_count) {
00276
00277
00278 LOG_EX(LOG_WARN, "%s: LE: invalid and/or unsupported relocations found.", file->get_filename());
00279 errorbox("%s: LE: invalid and/or unsupported relocations found.", file->get_filename());
00280 } else {
00281 LOG("%s: LE: relocations present, relocation simulation layer enabled", file->get_filename());
00282 }
00283 rfile->finalize();
00284 }
00285
00286 void ht_le::check_vxd()
00287 {
00288 ht_le_shared_data *le_shared = (ht_le_shared_data*)shared_data;
00289 FILEOFS h = le_shared->hdr_ofs;
00290
00291
00292 if (le_shared->is_vxd) {
00293
00294 LE_ENTRYPOINT_BUNDLE b;
00295 file->seek(h+le_shared->hdr.enttab);
00296 file->read(&b, sizeof b);
00297 le_shared->is_vxd = false;
00298 if ((b.entry_count == 1) && (b.flags & LE_ENTRYPOINT_BUNDLE_VALID) &&
00299 (b.flags & LE_ENTRYPOINT_BUNDLE_32BIT) && (b.obj_index == 1)) {
00300 LE_ENTRYPOINT32 e;
00301 file->read(&e, sizeof e);
00302 create_host_struct(&e, LE_ENTRYPOINT32_struct, le_shared->byteorder);
00303 if (e.flags & LE_ENTRYPOINT_EXPORTED) {
00304
00305 uint32 vxd_desc_ofs = (le_shared->objmap.header[0].
00306 page_map_index-1)*le_shared->hdr.pagesize + e.offset;
00307
00308 le_shared->reloc_file->seek(vxd_desc_ofs);
00309 le_shared->reloc_file->read(&le_shared->vxd_desc, sizeof le_shared->vxd_desc);
00310 create_host_struct(&le_shared->vxd_desc, LE_VXD_DESCRIPTOR_struct, le_shared->byteorder);
00311
00312 le_shared->vxd_desc_linear_ofs = vxd_desc_ofs;
00313 le_shared->is_vxd = true;
00314 }
00315 }
00316 }
00317 }
00318
00319 void ht_le::read_pagemap()
00320 {
00321 ht_le_shared_data *le_shared = (ht_le_shared_data*)shared_data;
00322 FILEOFS h = le_shared->hdr_ofs;
00323
00324 le_shared->pagemap.count=le_shared->hdr.pagecnt;
00325 le_shared->pagemap.offset=(dword*)malloc(le_shared->pagemap.count*sizeof *le_shared->pagemap.offset);
00326 le_shared->pagemap.psize=(dword*)malloc(le_shared->pagemap.count*sizeof *le_shared->pagemap.psize);
00327 le_shared->pagemap.vsize=(dword*)malloc(le_shared->pagemap.count*sizeof *le_shared->pagemap.vsize);
00328
00329 dword last_page_offset=0, last_page=0;
00330 for (dword i=0; i<le_shared->hdr.pagecnt; i++) {
00331 LE_PAGE_MAP_ENTRY e;
00332 file->seek(h+le_shared->hdr.pagemap+i*4);
00333 file->read(&e, sizeof e);
00334 create_host_struct(&e, LE_PAGE_MAP_ENTRY_struct, le_shared->byteorder);
00335
00336
00337 dword eofs=(e.high+e.low-1)*le_shared->hdr.pagesize+le_shared->hdr.datapage;
00338 le_shared->pagemap.offset[i] = eofs;
00339
00340 if (le_shared->pagemap.offset[i]>last_page_offset) {
00341 last_page_offset = le_shared->pagemap.offset[i];
00342 last_page = i;
00343 }
00344 }
00345
00346 for (dword i=0; i<le_shared->hdr.pagecnt; i++) {
00347 le_shared->pagemap.vsize[i]=0;
00348 if (i==last_page)
00349 le_shared->pagemap.psize[i]=le_shared->hdr.lastpagesize;
00350 else
00351 le_shared->pagemap.psize[i]=le_shared->hdr.pagesize;
00352 }
00353 }
00354
00355 void ht_le::read_objects()
00356 {
00357 ht_le_shared_data *le_shared = (ht_le_shared_data*)shared_data;
00358 FILEOFS h = le_shared->hdr_ofs;
00359
00360 le_shared->objmap.count = le_shared->hdr.objcnt;
00361 le_shared->objmap.header = (LE_OBJECT*)malloc(le_shared->objmap.count*sizeof *le_shared->objmap.header);
00362 le_shared->objmap.vsize = (UINT*)malloc(le_shared->objmap.count * sizeof *le_shared->objmap.vsize);
00363 le_shared->objmap.psize = (UINT*)malloc(le_shared->objmap.count * sizeof *le_shared->objmap.psize);
00364
00365 for (UINT i=0; i<le_shared->hdr.objcnt; i++) {
00366 file->seek(h+le_shared->hdr.objtab+i*24);
00367 file->read(&le_shared->objmap.header[i], sizeof *le_shared->objmap.header);
00368 create_host_struct(&le_shared->objmap.header[i], LE_OBJECT_HEADER_struct, le_shared->byteorder);
00369
00370
00371 UINT psize = 0;
00372 for (UINT j=0; j<le_shared->objmap.header[i].page_map_count; j++) {
00373 psize += le_shared->pagemap.psize[j+le_shared->objmap.header[i].page_map_index-1];
00374
00375 if (j == le_shared->objmap.header[i].page_map_count-1)
00376 le_shared->pagemap.vsize[j+le_shared->objmap.header[i].page_map_index-1]=le_shared->objmap.header[i].vsize % le_shared->hdr.pagesize;
00377 else
00378 le_shared->pagemap.vsize[j+le_shared->objmap.header[i].page_map_index-1]=le_shared->hdr.pagesize;
00379 }
00380
00381 #if 1
00382 le_shared->objmap.psize[i] = MIN(psize, le_shared->objmap.header[i].vsize);
00383 le_shared->objmap.vsize[i] = MIN(psize, le_shared->objmap.header[i].vsize);
00384 #else
00385 le_shared->objmap.psize[i] = le_shared->objmap.header[i].vsize;
00386 le_shared->objmap.vsize[i] = le_shared->objmap.header[i].vsize;
00387 #endif
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397 }
00398
00399 void ht_le::loc_enum_start()
00400 {
00401
00402 }
00403
00404 bool ht_le::loc_enum_next(ht_format_loc *loc)
00405 {
00406 #if 0
00407 ht_le_shared_data *sh=(ht_le_shared_data*)shared_data;
00408 if (loc_enum) {
00409 loc->name="le";
00410 loc->start=sh->hdr_ofs;
00411 loc->length=file->get_size()-loc->start;
00412
00413 loc_enum=false;
00414 return true;
00415 }
00416 #endif
00417 return false;
00418 }
00419
00420
00421
00422
00423
00424 void ht_le_page_file::init(ht_streamfile *file, bool own_file, ht_le_pagemap *pm, dword pms, dword ps)
00425 {
00426 ht_layer_streamfile::init(file, own_file);
00427 pagemap = pm;
00428 pagemapsize = pms;
00429 page_size = ps;
00430 ofs = 0;
00431 }
00432
00433 bool ht_le_page_file::isdirty(FILEOFS offset, UINT range)
00434 {
00435 FILEOFS mofs;
00436 UINT msize;
00437 while (range) {
00438 dword s=range;
00439 if (!map_ofs(offset, &mofs, &msize)) break;
00440 if (s>msize) s=msize;
00441 bool isdirty;
00442 streamfile->cntl(FCNTL_MODS_IS_DIRTY, mofs, s, &isdirty);
00443 if (isdirty) return 1;
00444 range-=s;
00445 ofs+=s;
00446 }
00447 return 0;
00448 }
00449
00454 bool ht_le_page_file::map_ofs(UINT lofs, FILEOFS *pofs, UINT *maxsize)
00455 {
00456 UINT i = lofs/page_size, j = lofs % page_size;
00457 if (i < pagemapsize) {
00458 if (j < pagemap->vsize[i]) {
00459 *pofs = pagemap->offset[i]+j;
00460 *maxsize = pagemap->vsize[i]-j;
00461 return true;
00462 }
00463 }
00464 return false;
00465 }
00466
00467 bool ht_le_page_file::unmap_ofs(FILEOFS pofs, UINT *lofs)
00468 {
00469 for (UINT i=0; i<pagemapsize; i++) {
00470 if ((pofs >= pagemap->offset[i]) && (pofs < pagemap->offset[i]+pagemap->vsize[i])) {
00471 *lofs = pofs - pagemap->offset[i] + i*page_size;
00472 return true;
00473 }
00474 }
00475 return false;
00476 }
00477
00478 UINT ht_le_page_file::read(void *aBuf, UINT size)
00479 {
00480 FILEOFS mofs;
00481 UINT msize;
00482 int c = 0;
00483 byte *buf = (byte *)aBuf;
00484 while (size) {
00485 UINT s = size;
00486 if (!map_ofs(ofs, &mofs, &msize)) break;
00487 if (s>msize) s = msize;
00488 streamfile->seek(mofs);
00489 s = streamfile->read(buf, s);
00490 if (!s) break;
00491 buf += s;
00492 size -= s;
00493 c += s;
00494 ofs += s;
00495 }
00496 return c;
00497 }
00498
00499 int ht_le_page_file::seek(FILEOFS offset)
00500 {
00501 ofs = offset;
00502 return 0;
00503 }
00504
00505 FILEOFS ht_le_page_file::tell()
00506 {
00507 return ofs;
00508 }
00509
00510 int ht_le_page_file::vcntl(UINT cmd, va_list vargs)
00511 {
00512 switch (cmd) {
00513 case FCNTL_MODS_CLEAR_DIRTY_RANGE: {
00514 FILEOFS o = va_arg(vargs, FILEOFS);
00515 UINT s = va_arg(vargs, UINT);
00516 UINT ts, ms;
00517 int e;
00518
00519 do {
00520 if (!map_ofs(o, &o, &ms)) return EINVAL;
00521 ts = (s < ms) ? s : ms;
00522 e = streamfile->cntl(cmd, o, ts);
00523 if (e) return e;
00524 s -= ts;
00525 } while (s);
00526 return 0;
00527 }
00528 case FCNTL_MODS_IS_DIRTY: {
00529 FILEOFS o = va_arg(vargs, FILEOFS);
00530 UINT s = va_arg(vargs, UINT);
00531 bool *b = va_arg(vargs, bool*);
00532 UINT ts, ms;
00533 int e;
00534
00535 *b = false;
00536 do {
00537 if (!map_ofs(o, &o, &ms)) return EINVAL;
00538 ts = (s < ms) ? s : ms;
00539 e = streamfile->cntl(cmd, o, ts, b);
00540 if (e) return e;
00541 if (*b) break;
00542 s -= ts;
00543 } while (s);
00544 return 0;
00545 }
00546 }
00547 return ht_layer_streamfile::vcntl(cmd, vargs);
00548 }
00549
00550 UINT ht_le_page_file::write(const void *aBuf, UINT size)
00551 {
00552 FILEOFS mofs;
00553 UINT msize;
00554 int c = 0;
00555 const byte *buf = (const byte *)aBuf;
00556 while (size) {
00557 UINT s = size;
00558 if (!map_ofs(ofs, &mofs, &msize)) break;
00559 if (s>msize) s = msize;
00560 streamfile->seek(mofs);
00561 buf += streamfile->write(buf, s);
00562 size -= s;
00563 c += s;
00564 ofs += s;
00565 }
00566 return c;
00567 }
00568
00569
00570
00571
00572
00573 ht_le_reloc_entry::ht_le_reloc_entry(UINT o, UINT s, LEAddress a, uint8 at, uint8 rt)
00574 {
00575 ofs = o;
00576 seg = s;
00577 addr = a;
00578 address_type = at;
00579 reloc_type = rt;
00580 }
00581
00582
00583
00584
00585
00586 void ht_le_reloc_file::init(ht_streamfile *s, bool os, ht_le_shared_data *d)
00587 {
00588 ht_reloc_file::init(s, os);
00589 data = d;
00590 }
00591
00592 void ht_le_reloc_file::reloc_apply(Object *reloc, byte *data)
00593 {
00594 ht_le_reloc_entry *e = (ht_le_reloc_entry*)reloc;
00595
00596 switch (e->address_type & LE_FIXUP_ADDR_TYPE_MASK) {
00597 case LE_FIXUP_ADDR_TYPE_0_8:
00598 create_foreign_int(data, e->addr, 1, little_endian);
00599 break;
00600 case LE_FIXUP_ADDR_TYPE_16_0:
00601 create_foreign_int(data, e->seg, 2, little_endian);
00602 break;
00603 case LE_FIXUP_ADDR_TYPE_16_16:
00604 create_foreign_int(data, e->addr, 2, little_endian);
00605 create_foreign_int(data, e->seg, 2, little_endian);
00606 break;
00607 case LE_FIXUP_ADDR_TYPE_0_16:
00608 create_foreign_int(data, e->addr, 2, little_endian);
00609 break;
00610 case LE_FIXUP_ADDR_TYPE_16_32:
00611 create_foreign_int(data, e->addr, 4, little_endian);
00612 create_foreign_int(data, e->seg, 2, little_endian);
00613 break;
00614 case LE_FIXUP_ADDR_TYPE_0_32:
00615 create_foreign_int(data, e->addr, 4, little_endian);
00616 break;
00617 case LE_FIXUP_ADDR_TYPE_REL32:
00618 create_foreign_int(data, e->addr - LE_BASE_ADDR - e->ofs - 4, 4, little_endian);
00619 break;
00620 }
00621 }
00622
00623 bool ht_le_reloc_file::reloc_unapply(Object *reloc, byte *data)
00624 {
00625 return false;
00626 }
00627
00628
00629
00630
00631
00632 FILEOFS LE_get_seg_ofs(ht_le_shared_data *LE_shared, UINT i)
00633 {
00634 assert(i<LE_shared->objmap.count);
00635 return LE_SEG_ADDR(i) - LE_BASE_ADDR;
00636 }
00637
00638 LEAddress LE_get_seg_addr(ht_le_shared_data *LE_shared, UINT i)
00639 {
00640 assert(i<LE_shared->objmap.count);
00641 return LE_SEG_ADDR(i);
00642 }
00643
00644 UINT LE_get_seg_psize(ht_le_shared_data *LE_shared, UINT i)
00645 {
00646 assert(i<LE_shared->objmap.count);
00647 return LE_shared->objmap.psize[i];
00648 }
00649
00650 UINT LE_get_seg_vsize(ht_le_shared_data *LE_shared, UINT i)
00651 {
00652 assert(i<LE_shared->objmap.count);
00653 return LE_shared->objmap.vsize[i];
00654 }
00655
00656 bool LE_addr_to_segment(ht_le_shared_data *LE_shared, LEAddress Addr, int *segment)
00657 {
00658 for (UINT i = 0; i < LE_shared->objmap.count; i++) {
00659 LEAddress base = LE_get_seg_addr(LE_shared, i);
00660 UINT evsize = MAX(LE_get_seg_vsize(LE_shared, i), LE_get_seg_psize(LE_shared, i));
00661 if ((Addr >= base) && (Addr < base + evsize)) {
00662 *segment = i;
00663 return true;
00664 }
00665 }
00666 return false;
00667 }
00668
00669 bool LE_addr_is_physical(ht_le_shared_data *LE_shared, LEAddress Addr)
00670 {
00671 for (UINT i = 0; i < LE_shared->objmap.count; i++) {
00672 LEAddress base = LE_get_seg_addr(LE_shared, i);
00673 UINT psize = LE_get_seg_psize(LE_shared, i);
00674 if ((Addr >= base) && (Addr < base + psize)) return true;
00675 }
00676 return false;
00677 }
00678
00679 bool LE_addr_to_ofs(ht_le_shared_data *LE_shared, LEAddress Addr, FILEOFS *ofs)
00680 {
00681 for (UINT i = 0; i < LE_shared->objmap.count; i++) {
00682 LEAddress base = LE_get_seg_addr(LE_shared, i);
00683 UINT psize = LE_get_seg_psize(LE_shared, i);
00684 if ((Addr >= base) && (Addr < base + psize)) {
00685 *ofs = Addr - LE_BASE_ADDR;
00686 return true;
00687 }
00688 }
00689 return false;
00690 }
00691
00692 bool LE_ofs_to_addr(ht_le_shared_data *LE_shared, FILEOFS ofs, LEAddress *Addr)
00693 {
00694 for (UINT i = 0; i < LE_shared->objmap.count; i++) {
00695 FILEOFS sofs = LE_get_seg_ofs(LE_shared, i);
00696 if ((ofs >= sofs) && (ofs < sofs + LE_get_seg_psize(LE_shared, i))) {
00697 *Addr = LE_BASE_ADDR + ofs;
00698 return true;
00699 }
00700 }
00701 return false;
00702 }
00703
00704 LEAddress LE_MAKE_ADDR(ht_le_shared_data *LE_shared, uint16 seg, uint32 ofs)
00705 {
00706 return LE_SEG_ADDR(seg) + ofs;
00707 }
00708
00709 uint16 LE_ADDR_SEG(ht_le_shared_data *LE_shared, LEAddress a)
00710 {
00711 for (UINT i = 0; i<LE_shared->objmap.count; i++) {
00712 LEAddress addr = LE_SEG_ADDR(i);
00713 if ((a >= addr) && (a < addr + LE_shared->objmap.vsize[i])) {
00714 return i;
00715 }
00716 }
00717 return 0xffff;
00718 }
00719
00720 uint32 LE_ADDR_OFS(ht_le_shared_data *LE_shared, LEAddress a)
00721 {
00722 for (UINT i = 0; i<LE_shared->objmap.count; i++) {
00723 LEAddress addr = LE_SEG_ADDR(i);
00724 if ((a >= addr) && (a < addr + LE_shared->objmap.vsize[i])) {
00725 return a-addr;
00726 }
00727 }
00728 return 0;
00729 }
00730