Skip to content

Commit

Permalink
i#58 MacOS: fixes for Mavericks (10.9)
Browse files Browse the repository at this point in the history
Handle the increased vm_region_submap_info_64 size.
Handle the re-arranged shared cache with __LINKEDIT that extends beyond the
cache end: we truncate and disregard the Mach-O size field.

SVN-Revision: 2542
  • Loading branch information
derekbruening committed Feb 19, 2014
1 parent 9e666ef commit fae559b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 8 deletions.
2 changes: 1 addition & 1 deletion core/unix/memquery.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ typedef struct _memquery_iter_t {
* without using static data and limiting to one iterator (and having
* to unprotect and reprotect if in .data).
*/
# define MEMQUERY_INTERNAL_DATA_LEN 80 /* 72 bytes needed for Mac */
# define MEMQUERY_INTERNAL_DATA_LEN 96 /* 84 bytes needed for Mac 10.9.1 */
char internal[MEMQUERY_INTERNAL_DATA_LEN];
} memquery_iter_t;

Expand Down
30 changes: 23 additions & 7 deletions core/unix/module_macho.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,20 +225,36 @@ module_walk_program_headers(app_pc base, size_t view_size, bool at_map,
/* skip */
} else {
app_pc seg_start = (app_pc) seg->vmaddr + load_delta;
size_t seg_size = seg->vmsize;
bool shared = false;
if (strcmp(seg->segname, "__LINKEDIT") == 0 &&
have_shared && seg_start >= shared_start &&
seg_start < shared_end) {
/* We assume that all __LINKEDIT segments in the
* dyld cache are shared as one single segment.
*/
shared = true;
/* XXX: seg->vmsize is too large for these: it extends
* off the end of the mapping. I have no idea why.
* So we truncate it. We leave max_end above.
*/
if (seg_start + seg->vmsize > shared_end) {
LOG(GLOBAL, LOG_VMAREAS, 4,
"%s: truncating __LINKEDIT size from "PIFX
" to "PIFX"\n", __FUNCTION__, seg->vmsize,
shared_end - seg_start);
seg_size = shared_end - seg_start;
}
}
module_add_segment_data
(out_data, 0/*don't know*/, seg_start, seg->vmsize,
(out_data, 0/*don't know*/, seg_start, seg_size,
/* we want initprot, not maxprot, right? */
vmprot_to_memprot(seg->initprot),
/* XXX: alignment is specified per section --
* ignoring for now
*/
PAGE_SIZE,
/* we assume that all __LINKEDIT segments in the
* dyld cache are shared as one single segment
*/
strcmp(seg->segname, "__LINKEDIT") == 0 &&
have_shared && seg_start >= shared_start &&
seg_start + seg->vmsize < shared_end);
shared);
}
} else if (cmd->cmd == LC_SYMTAB) {
/* even if stripped, dynamic symbols are in this table */
Expand Down

0 comments on commit fae559b

Please sign in to comment.