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
00032
00033
00034 #include <sys/stat.h>
00035 #include <sys/types.h>
00036 #include <sys/mman.h>
00037 #include <fcntl.h>
00038 #include <unistd.h>
00039 #include <string.h>
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <sysexits.h>
00043 #include <assert.h>
00044 #include <dirent.h>
00045
00046 #define _M_DEBUG_BUILD
00047 #include <debug.h>
00048 #include <result.h>
00049
00050 #include "mcore_i.h"
00051 #include "files.h"
00052 #include "segment.h"
00053 #include "module.h"
00054 #include "hal/pcm_i.h"
00055 #include "pregionlayout.h"
00056 #include "config.h"
00057
00058
00062 #define SEGMENTS_DIR mcore_runtime_settings.segments_dir
00063
00064
00065 #define M_DEBUG_SEGMENT 1
00066
00067 m_segtbl_t m_segtbl;
00068
00069
00070
00071 #undef TRY_ALLOC_IN_HOLES
00072
00073
00074 static inline void *segment_map(void *addr, size_t size, int prot, int flags, int segment_fd);
00075 static m_result_t segidx_find_entry_using_index(m_segidx_t *segidx, uint32_t index, m_segidx_entry_t **entryp);
00076
00077
00089 static
00090 void
00091 verify_backing_stores(m_segtbl_t *segtbl)
00092 {
00093 int n;
00094 DIR *d;
00095 struct dirent *dir;
00096 uint32_t index;
00097 uint32_t segment_id;
00098 uint64_t segment_module_id;
00099 m_segidx_entry_t *ientry;
00100 char complete_path[256];
00101
00102 d = opendir(SEGMENTS_DIR);
00103 if (d) {
00104 while ((dir = readdir(d)) != NULL) {
00105 n = sscanf(dir->d_name, "%u.%lu\n", &segment_id, &segment_module_id);
00106 if (n == 2) {
00107 index = segment_id;
00108 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "Verifying backing store: %u.%lu\n", segment_id, segment_module_id);
00109
00110 if (!(segtbl->entries[index].flags & SGTB_VALID_ENTRY)) {
00111
00112 sprintf(complete_path, "%s/%s", SEGMENTS_DIR, dir->d_name);
00113 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "Remove backing store: %s\n", complete_path);
00114 unlink(complete_path);
00115 }
00116
00117 if (segment_module_id != (uint64_t) (-1LLU)) {
00118 if (segidx_find_entry_using_index(segtbl->idx, index, &ientry)
00119 != M_R_SUCCESS)
00120 {
00121 M_INTERNALERROR("Cannot find index entry for valid table entry.");
00122 }
00123 ientry->module_id = segment_module_id;
00124 }
00125 }
00126 }
00127 closedir(d);
00128 }
00129 }
00130
00131
00132 static
00133 int
00134 create_backing_store(char *file, size_t size)
00135 {
00136 int fd;
00137 ssize_t roundup_size;
00138 char buf[1];
00139
00140 fd = open(file, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR);
00141 if (fd < 0) {
00142 return fd;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 roundup_size = SIZEOF_PAGES(size);
00157 assert(lseek(fd, roundup_size, SEEK_SET) != (off_t) -1);
00158 write(fd, buf, 1);
00159 fsync(fd);
00160
00161
00162 return fd;
00163 }
00164
00165 m_result_t
00166 m_check_backing_store(char *path, ssize_t size)
00167 {
00168 m_result_t rv = M_R_FAILURE;
00169 struct stat stat_buf;
00170 ssize_t roundup_size;
00171
00172 if (stat(path, &stat_buf)==0) {
00173 roundup_size = SIZEOF_PAGES(size);
00174 if (stat_buf.st_size > roundup_size) {
00175 rv = M_R_SUCCESS;
00176 } else {
00177 rv = M_R_FAILURE;
00178 }
00179 }
00180 return rv;
00181 }
00182
00183 static
00184 m_result_t
00185 segidx_insert_entry_ordered(m_segidx_t *segidx, m_segidx_entry_t *new_entry, int lock)
00186 {
00187 m_segidx_entry_t *ientry;
00188
00189 if (lock) {
00190 pthread_mutex_lock(&(segidx->mutex));
00191 }
00192
00193
00194
00195
00196 list_for_each_entry(ientry, &(segidx->mapped_entries.list), list) {
00197 if (ientry->segtbl_entry->start > new_entry->segtbl_entry->start) {
00198 list_add_tail(&(new_entry->list), &(ientry->list));
00199 goto out;
00200 }
00201 }
00202 list_add_tail(&(new_entry->list), &(segidx->mapped_entries.list));
00203
00204 out:
00205 if (lock) {
00206 pthread_mutex_unlock(&(segidx->mutex));
00207 }
00208 return M_R_SUCCESS;
00209 }
00210
00211
00212 m_result_t
00213 segidx_create(m_segtbl_t *_segtbl, m_segidx_t **_segidxp)
00214 {
00215 m_result_t rv;
00216 m_segidx_t *_segidx;
00217 m_segidx_entry_t *entries;
00218 m_segtbl_entry_t *segtbl_entry;
00219 int i;
00220
00221 if (!(_segidx = (m_segidx_t *) malloc(sizeof(m_segidx_t)))) {
00222 rv = M_R_NOMEMORY;
00223 goto out;
00224 }
00225
00226 if (!(entries = (m_segidx_entry_t *) calloc(SEGMENT_TABLE_NUM_ENTRIES,
00227 sizeof(m_segidx_entry_t))))
00228 {
00229 rv = M_R_NOMEMORY;
00230 goto err_calloc;
00231 }
00232 pthread_mutex_init(&(_segidx->mutex), NULL);
00233 _segidx->all_entries = entries;
00234 INIT_LIST_HEAD(&(_segidx->mapped_entries.list));
00235 INIT_LIST_HEAD(&(_segidx->free_entries.list));
00236 for (i=0; i < SEGMENT_TABLE_NUM_ENTRIES; i++) {
00237 segtbl_entry = entries[i].segtbl_entry = &_segtbl->entries[i];
00238 entries[i].index = i;
00239 entries[i].module_id = (uint64_t) (-1ULL);
00240 if (segtbl_entry->flags & SGTB_VALID_ENTRY) {
00241 segidx_insert_entry_ordered(_segidx, &(entries[i]), 0);
00242 } else {
00243 list_add_tail(&(entries[i].list), &(_segidx->free_entries.list));
00244 }
00245 }
00246 *_segidxp = _segidx;
00247 rv = M_R_SUCCESS;
00248 goto out;
00249 err_calloc:
00250 free(_segidx);
00251 out:
00252 return rv;
00253 }
00254
00255
00256 static
00257 m_result_t
00258 segidx_destroy(m_segidx_t *segidx)
00259 {
00260 M_INTERNALERROR("Unimplemented functionality: segidx_destroy\n");
00261 return M_R_SUCCESS;
00262 }
00263
00264
00265 static
00266 m_result_t
00267 segidx_alloc_entry(m_segidx_t *segidx, m_segidx_entry_t **entryp)
00268 {
00269 m_result_t rv = M_R_FAILURE;
00270 m_segidx_entry_t *entry;
00271 struct list_head *free_head;
00272
00273
00274 pthread_mutex_lock(&(segidx->mutex));
00275 if ((free_head = segidx->free_entries.list.next)) {
00276 entry = list_entry(free_head, m_segidx_entry_t, list);
00277 list_del_init(&(entry->list));
00278 } else {
00279 rv = M_R_NOMEMORY;
00280 goto out;
00281 }
00282 *entryp = entry;
00283 rv = M_R_SUCCESS;
00284 goto out;
00285
00286 out:
00287 pthread_mutex_unlock(&(segidx->mutex));
00288 return rv;
00289 }
00290
00291
00292 static
00293 m_result_t
00294 segidx_free_entry(m_segidx_t *segidx, m_segidx_entry_t *entry)
00295 {
00296 m_result_t rv = M_R_FAILURE;
00297
00298 if (!entry) {
00299 rv = M_R_INVALIDARG;
00300 return rv;
00301 }
00302
00303 pthread_mutex_lock(&(segidx->mutex));
00304 list_del_init(&(entry->list));
00305 list_add(&(entry->list), &(segidx->free_entries.list));
00306 rv = M_R_SUCCESS;
00307 goto unlock;
00308
00309 unlock:
00310 pthread_mutex_unlock(&(segidx->mutex));
00311 return rv;
00312 }
00313
00314
00315
00316 static
00317 m_result_t
00318 segidx_find_entry_using_addr(m_segidx_t *segidx, void *addr, m_segidx_entry_t **entryp)
00319 {
00320 m_segidx_entry_t *ientry;
00321 m_segtbl_entry_t *tentry;
00322 uintptr_t start;
00323 uint32_t size;
00324
00325 list_for_each_entry(ientry, &segidx->mapped_entries.list, list) {
00326 tentry = ientry->segtbl_entry;
00327 start = tentry->start;
00328 size = tentry->size;
00329 if ((uintptr_t) addr >= start && (uintptr_t) addr < start+size) {
00330 *entryp = ientry;
00331 return M_R_SUCCESS;
00332 }
00333 }
00334 return M_R_FAILURE;
00335 }
00336
00337
00338
00339
00340 static
00341 m_result_t
00342 segidx_find_entry_using_index(m_segidx_t *segidx, uint32_t index, m_segidx_entry_t **entryp)
00343 {
00344 if (index >= SEGMENT_TABLE_NUM_ENTRIES) {
00345 return M_R_INVALIDARG;
00346 }
00347 *entryp = &segidx->all_entries[index];
00348 return M_R_SUCCESS;
00349 }
00350
00351
00352
00353 static
00354 m_result_t
00355 segidx_find_entry_using_module_id(m_segidx_t *segidx, uint64_t module_id, m_segidx_entry_t **entryp)
00356 {
00357 m_segidx_entry_t *ientry;
00358
00359 list_for_each_entry(ientry, &segidx->mapped_entries.list, list) {
00360 if (ientry->module_id == module_id) {
00361 *entryp = ientry;
00362 return M_R_SUCCESS;
00363 }
00364 }
00365 return M_R_FAILURE;
00366 }
00367
00368 static
00369 uintptr_t
00370 segidx_find_free_region(m_segidx_t *segidx, uintptr_t start_addr, size_t length)
00371 {
00372 struct list_head *tmp_list;
00373 m_segidx_entry_t *max_ientry;
00374
00375 pthread_mutex_lock(&segidx->mutex);
00376 if ((tmp_list = segidx->mapped_entries.list.prev) != &segidx->mapped_entries.list) {
00377 max_ientry = list_entry(tmp_list, m_segidx_entry_t, list);
00378 if (start_addr < (max_ientry->segtbl_entry->start + max_ientry->segtbl_entry->size)) {
00379 start_addr = 0x0;
00380 #ifdef TRY_ALLOC_IN_HOLES
00381
00382 prev_end_addr = SEGMENT_MAP_START;
00383 list_for_each_entry(ientry, &(segidx->mapped_entries.list), list) {
00384 if (ientry->segtbl_entry->start - prev_end_addr > length) {
00385 start_addr = prev_end_addr;
00386 break;
00387 }
00388 prev_end_addr = ientry->segtbl_entry->start + ientry->segtbl_entry->size;
00389 }
00390 #endif
00391
00392 if (!start_addr) {
00393 start_addr = max_ientry->segtbl_entry->start + max_ientry->segtbl_entry->size;
00394 }
00395 }
00396 }
00397 pthread_mutex_unlock(&segidx->mutex);
00398 return start_addr;
00399 }
00400
00401
00402 static inline
00403 m_result_t
00404 segment_table_map(m_segtbl_t *segtbl)
00405 {
00406 char segtbl_path[256];
00407 int segtbl_fd;
00408
00409 sprintf(segtbl_path, "%s/segment_table", SEGMENTS_DIR);
00410 if (m_check_backing_store(segtbl_path, SEGMENT_TABLE_SIZE) != M_R_SUCCESS) {
00411 mkdir_r(SEGMENTS_DIR, S_IRWXU);
00412 segtbl_fd = create_backing_store(segtbl_path, SEGMENT_TABLE_SIZE);
00413 } else {
00414 segtbl_fd = open(segtbl_path, O_RDWR);
00415 }
00416 segtbl->entries = segment_map((void *) SEGMENT_TABLE_START,
00417 SEGMENT_TABLE_SIZE,
00418 PROT_READ|PROT_WRITE,
00419 MAP_PERSISTENT | MAP_SHARED,
00420 segtbl_fd);
00421 if (segtbl->entries == MAP_FAILED) {
00422 assert(0 && "Going crazy...couldn't map the segment table\n");
00423 return M_R_FAILURE;
00424 }
00425 return M_R_SUCCESS;
00426 }
00427
00428
00437 static
00438 m_result_t
00439 segment_table_incarnate()
00440 {
00441 m_result_t rv;
00442
00443 if ((rv = segment_table_map(&m_segtbl)) != M_R_SUCCESS) {
00444 return rv;
00445 }
00446 if ((rv = segidx_create(&m_segtbl, &(m_segtbl.idx))) != M_R_SUCCESS) {
00447
00448 }
00449 verify_backing_stores(&m_segtbl);
00450
00451 return M_R_SUCCESS;
00452 }
00453
00454
00455 static inline
00456 void
00457 segment_table_print(m_segtbl_t *segtbl)
00458 {
00459 m_segidx_entry_t *ientry;
00460 m_segtbl_entry_t *tentry;
00461 uintptr_t start;
00462 uintptr_t end;
00463
00464 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "PERSISTENT SEGMENT TABLE\n");
00465 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "========================\n");
00466 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "%16s %16s %17s %10s\n", "start", "end", "size", "flags");
00467 list_for_each_entry(ientry, &segtbl->idx->mapped_entries.list, list) {
00468 tentry = ientry->segtbl_entry;
00469 start = (uintptr_t) tentry->start;
00470 end = (uintptr_t) tentry->start + (uintptr_t) tentry->size;
00471 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "0x%016lx - 0x%016lx %16luK", start, end, (long unsigned int) tentry->size/1024);
00472 M_DEBUG_PRINT(M_DEBUG_SEGMENT, " %7c%c%c%c\n", ' ',
00473 (tentry->flags & SGTB_VALID_ENTRY)? 'V': '-',
00474 (tentry->flags & SGTB_VALID_DATA)? 'D': '-',
00475 (tentry->flags & SGTB_TYPE_SECTION)? 'S': '-'
00476 );
00477 }
00478 }
00479
00480
00481 void
00482 m_segment_table_print()
00483 {
00484 segment_table_print(&m_segtbl);
00485 }
00486
00487
00488 m_result_t
00489 m_segment_table_alloc_entry(m_segtbl_t *segtbl, m_segtbl_entry_t **entryp)
00490 {
00491 m_result_t rv;
00492 m_segidx_entry_t *ientry;
00493
00494 rv = segidx_alloc_entry(segtbl->idx, &ientry);
00495 if (rv != M_R_SUCCESS) {
00496 goto out;
00497 }
00498 *entryp = ientry->segtbl_entry;
00499
00500 out:
00501 return rv;
00502 }
00503
00504
00508 static inline
00509 void *
00510 segment_map(void *addr, size_t size, int prot, int flags, int segment_fd)
00511 {
00512 void *segmentp;
00513 uintptr_t start;
00514 uintptr_t end;
00515
00516
00517 if (segment_fd < 0) {
00518 return ((void *) -1);
00519 }
00520 segmentp = mmap(addr, size, prot,
00521 flags | MAP_PERSISTENT| MAP_SHARED,
00522 segment_fd,
00523 0);
00524
00525 if (segmentp == MAP_FAILED) {
00526 return segmentp;
00527 }
00528
00529
00530
00531
00532 start = (uintptr_t) segmentp;
00533 end = start + size;
00534 if (start < PSEGMENT_RESERVED_REGION_START ||
00535 start > PSEGMENT_RESERVED_REGION_END ||
00536 end > PSEGMENT_RESERVED_REGION_END)
00537 {
00538
00539 M_DEBUG_PRINT(M_DEBUG_SEGMENT, " limits : %016lx - %016lx\n", PSEGMENT_RESERVED_REGION_START, PSEGMENT_RESERVED_REGION_END);
00540 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "asked for : %016lx - %016lx\n", (uintptr_t) addr, (uintptr_t) addr + size);
00541 M_DEBUG_PRINT(M_DEBUG_SEGMENT, " got : %016lx - %016lx\n", start, end);
00542 M_INTERNALERROR("Persistent segment not in the reserved address space region.\n");
00543 return MAP_FAILED;
00544 }
00545
00546
00547 if (madvise(segmentp, size, MADV_RANDOM) < 0) {
00548 return MAP_FAILED;
00549 }
00550 return segmentp;
00551 }
00552
00553
00557 static
00558 void *
00559 segment_map2(void *addr, size_t size, int prot, int flags, char *segment_path)
00560 {
00561 int segment_fd;
00562 void *segmentp;
00563
00564 segment_fd = open(segment_path, O_RDWR);
00565 if (segment_fd < 0) {
00566 return ((void *) -1);
00567 }
00568
00569 segmentp = segment_map(addr, size, prot, flags, segment_fd);
00570
00571 if (segmentp == MAP_FAILED) {
00572 close (segment_fd);
00573 return segmentp;
00574 }
00575 return segmentp;
00576 }
00577
00578
00584 void
00585 segment_reincarnate_segments(m_segtbl_t *segtbl)
00586 {
00587 m_segidx_entry_t *ientry;
00588 m_segtbl_entry_t *tentry;
00589 uintptr_t start;
00590 uintptr_t end;
00591 char path[256];
00592 void *map_addr;
00593
00594 list_for_each_entry(ientry, &segtbl->idx->mapped_entries.list, list) {
00595 tentry = ientry->segtbl_entry;
00596 if (tentry->flags & SGTB_TYPE_PMAP) {
00597 sprintf(path, "%s/%d.0", SEGMENTS_DIR, ientry->index);
00598 } else if (tentry->flags & SGTB_TYPE_SECTION) {
00599 sprintf(path, "%s/%d.%lu", SEGMENTS_DIR, ientry->index, (long unsigned int) ientry->module_id);
00600 } else {
00601 M_INTERNALERROR("Unknown persistent segment type.\n");
00602 }
00603 start = (uintptr_t) tentry->start;
00604 end = (uintptr_t) tentry->start + (uintptr_t) tentry->size;
00605
00606
00607
00608
00609
00610 map_addr = segment_map2((void *) start, (size_t) tentry->size,
00611 PROT_READ|PROT_WRITE,
00612 MAP_FIXED,
00613 path);
00614 if (map_addr == MAP_FAILED) {
00615 M_INTERNALERROR("Cannot reincarnate persistent segment.\n");
00616 }
00617 }
00618 }
00619
00620
00621 static
00622 void *
00623 pmap_internal_abs(void *start, size_t length, int prot, int flags,
00624 m_segidx_entry_t **entryp, uint32_t segtbl_entry_flags, uint64_t module_id)
00625 {
00626 char path[256];
00627 uintptr_t start_addr = (uintptr_t) start;
00628 void *map_addr;
00629 int fd;
00630 void *rv = MAP_FAILED;
00631 m_segidx_entry_t *new_ientry;
00632 m_segtbl_entry_t *tentry;
00633 uint32_t flags_val;
00634
00635
00636 if ((segidx_alloc_entry(m_segtbl.idx, &new_ientry)) != M_R_SUCCESS) {
00637 rv = MAP_FAILED;
00638 goto out;
00639 }
00640 sprintf(path, "%s/%d.%lu", SEGMENTS_DIR, new_ientry->index, module_id);
00641
00642
00643
00644
00645
00646
00647 length = SIZEOF_PAGES(length);
00648
00649 if ((fd = create_backing_store(path, length)) < 0) {
00650 rv = MAP_FAILED;
00651 goto err_create_backing_store;
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "start_addr = %p\n", (void *) start_addr);
00662
00663 if ((flags & MAP_FIXED) != MAP_FIXED) {
00664 start_addr = segidx_find_free_region(m_segtbl.idx, start_addr, length);
00665 }
00666 map_addr = segment_map((void *)start_addr, length, prot, flags, fd);
00667 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "new_start_addr = %p\n", (void *) start_addr);
00668 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "map_addr = %p\n", map_addr);
00669 if (map_addr == MAP_FAILED) {
00670 rv = MAP_FAILED;
00671 goto err_segment_map;
00672 }
00673
00674
00675 tentry = new_ientry->segtbl_entry;
00676 tentry->start = map_addr;
00677 tentry->size = length;
00678 PCM_WB_FENCE(NULL);
00679 PCM_WB_FLUSH(NULL, &(tentry->start));
00680 PCM_WB_FLUSH(NULL, &(tentry->size));
00681 flags_val = segtbl_entry_flags;
00682 tentry->flags = flags_val;
00683 PCM_WB_FENCE(NULL);
00684 PCM_WB_FLUSH(NULL, &(tentry->flags));
00685
00686
00687 segidx_insert_entry_ordered(m_segtbl.idx, new_ientry, 1);
00688
00689 *entryp = new_ientry;
00690 rv = map_addr;
00691 goto out;
00692
00693 err_segment_map:
00694 err_create_backing_store:
00695 segidx_free_entry(m_segtbl.idx, new_ientry);
00696 out:
00697 return rv;
00698 }
00699
00700
00701 static
00702 void *
00703 pmap_internal(void *start, size_t length, int prot, int flags,
00704 m_segidx_entry_t **entryp, uint32_t segtbl_entry_flags, uint64_t module_id)
00705 {
00706 uintptr_t start_addr = SEGMENT_MAP_START + (uintptr_t) start;
00707
00708 segment_table_print(&m_segtbl);
00709 return pmap_internal_abs((void *) start_addr, length, prot, flags,
00710 entryp, segtbl_entry_flags, module_id);
00711 }
00712
00713
00714
00719 static
00720 m_result_t
00721 segment_create_sections(m_segtbl_t *segtbl)
00722 {
00723 void *mapped_addr;
00724 size_t length;
00725 uintptr_t persistent_section_absolute_addr;
00726 uintptr_t GOT_section_absolute_addr;
00727 m_result_t rv;
00728 module_dsr_t *module_dsr;
00729 m_segtbl_entry_t *tentry;
00730 m_segidx_entry_t *ientry;
00731 uint32_t flags_val;
00732 Elf_Data *elfdata;
00733
00734 rv = m_module_create_module_dsr_list(&module_dsr_list);
00735
00736 list_for_each_entry(module_dsr, &module_dsr_list, list) {
00737 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "module_path = %s\n", module_dsr->module_path);
00738 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "module_id = %lu\n", module_dsr->module_inode);
00739
00740
00741
00742
00743
00744 if (segidx_find_entry_using_module_id(segtbl->idx, module_dsr->module_inode, &ientry)
00745 != M_R_SUCCESS)
00746 {
00747 length = module_dsr->persistent_shdr.sh_size;
00748 mapped_addr = pmap_internal(0, length, PROT_READ|PROT_WRITE, 0, &ientry,
00749 SGTB_TYPE_SECTION | SGTB_VALID_ENTRY, module_dsr->module_inode);
00750 if (mapped_addr == MAP_FAILED) {
00751 M_INTERNALERROR("Cannot map .persistent section's segment.\n");
00752 }
00753 } else {
00754 mapped_addr = (void *) ientry->segtbl_entry->start;
00755 length = ientry->segtbl_entry->size;
00756 }
00757
00758
00759
00760
00761
00762
00763 persistent_section_absolute_addr = (uintptr_t) (module_dsr->persistent_shdr.sh_addr+module_dsr->module_start-0x400000);
00764 GOT_section_absolute_addr = (uintptr_t) (module_dsr->GOT_shdr.sh_addr+module_dsr->module_start-0x400000);
00765
00766 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "persistent_section.start = %p\n",
00767 (void *) persistent_section_absolute_addr);
00768 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "persistent_section.end = %p\n",
00769 (void *) (persistent_section_absolute_addr +
00770 module_dsr->persistent_shdr.sh_size));
00771 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "persistent_section.sh_size = %d\n",
00772 (int) module_dsr->persistent_shdr.sh_size);
00773 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "persistent_section.sh_size_pages = %d\n",
00774 (int) SIZEOF_PAGES(module_dsr->persistent_shdr.sh_size));
00775 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "GOT_section.start = %p\n",
00776 (void *) GOT_section_absolute_addr);
00777 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "GOT_section.end = %p\n",
00778 (void *) GOT_section_absolute_addr+module_dsr->GOT_shdr.sh_size);
00779 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "GOT_section.sh_size = %d\n",
00780 (int) module_dsr->GOT_shdr.sh_size);
00781
00782
00783 m_module_relocate_symbols(GOT_section_absolute_addr,
00784 GOT_section_absolute_addr + module_dsr->GOT_shdr.sh_size,
00785 persistent_section_absolute_addr,
00786 persistent_section_absolute_addr + module_dsr->persistent_shdr.sh_size,
00787 (uintptr_t) mapped_addr,
00788 (uintptr_t) mapped_addr+length
00789 );
00790
00791
00792 if (!(ientry->segtbl_entry->flags & SGTB_VALID_DATA))
00793 {
00794 elfdata = NULL;
00795 while ((elfdata = elf_getdata(module_dsr->persistent_scn, elfdata)))
00796 {
00797 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "data.d_size = %d\n", (int) elfdata->d_size);
00798 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "data.d_buf = %p\n", elfdata->d_buf);
00799 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "start_addr = %lx\n", (uintptr_t) mapped_addr);
00800 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "end_addr = %lx\n", (uintptr_t) mapped_addr + length);
00801 M_DEBUG_PRINT(M_DEBUG_SEGMENT, "length = %u\n", (unsigned int) length);
00802 memcpy(mapped_addr, elfdata->d_buf, elfdata->d_size);
00803 }
00804
00805 tentry = ientry->segtbl_entry;
00806 flags_val = tentry->flags | SGTB_VALID_DATA;
00807 tentry->flags = flags_val;
00808 PCM_WB_FENCE(NULL);
00809 PCM_WB_FLUSH(NULL, &(tentry->flags));
00810 }
00811
00812 }
00813
00814 return M_R_SUCCESS;
00815 }
00816
00817
00818
00823 m_result_t
00824 m_segmentmgr_init()
00825 {
00826 char buf[256];
00827
00828
00829 if (mcore_runtime_settings.reset_segments) {
00830
00831 sprintf(buf, "rm -rf %s", SEGMENTS_DIR);
00832 system(buf);
00833 }
00834
00835 segment_table_incarnate();
00836 segment_reincarnate_segments(&m_segtbl);
00837 segment_create_sections(&m_segtbl);
00838
00839 segment_table_print(&m_segtbl);
00840
00841 return M_R_SUCCESS;
00842 }
00843
00844
00848 m_result_t
00849 m_segmentmgr_fini()
00850 {
00851
00852 return M_R_SUCCESS;
00853 }
00854
00855
00856
00857 m_result_t
00858 m_segment_find_using_addr(void *addr, m_segidx_entry_t **entryp)
00859 {
00860 return segidx_find_entry_using_addr(m_segtbl.idx, addr, entryp);
00861 }
00862
00863
00864
00870 void *
00871 m_pmap(void *start, size_t length, int prot, int flags)
00872 {
00873 m_segidx_entry_t *ientry;
00874 void *rv;
00875 rv = pmap_internal(start, length, prot, flags, &ientry,
00876 SGTB_TYPE_PMAP | SGTB_VALID_ENTRY | SGTB_VALID_DATA, 0);
00877 return rv;
00878 }
00879
00880
00885 void *
00886 m_pmap2(void *start, size_t length, int prot, int flags)
00887 {
00888 m_segidx_entry_t *ientry;
00889 void *rv;
00890
00891 rv = pmap_internal_abs(start, length, prot, flags, &ientry,
00892 SGTB_TYPE_PMAP | SGTB_VALID_ENTRY | SGTB_VALID_DATA, 0);
00893 return rv;
00894 }
00895
00896
00897
00898 int
00899 m_punmap(void *start, size_t length)
00900 {
00901 M_INTERNALERROR("Unimplemented functionality: m_punmap\n");
00902 return 0;
00903 }