@@ -3678,8 +3678,8 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
* to mmap pages in this space.
*/
if (info->reserve_brk) {
- abi_ulong start_brk = HOST_PAGE_ALIGN(info->brk);
- abi_ulong end_brk = HOST_PAGE_ALIGN(info->brk + info->reserve_brk);
+ abi_ulong start_brk = TARGET_PAGE_ALIGN(info->brk);
+ abi_ulong end_brk = TARGET_PAGE_ALIGN(info->brk + info->reserve_brk);
target_munmap(start_brk, end_brk - start_brk);
}
@@ -802,81 +802,51 @@ static inline int host_to_target_sock_type(int host_type)
}
static abi_ulong target_brk, initial_target_brk;
-static abi_ulong brk_page;
void target_set_brk(abi_ulong new_brk)
{
target_brk = TARGET_PAGE_ALIGN(new_brk);
initial_target_brk = target_brk;
- brk_page = HOST_PAGE_ALIGN(target_brk);
}
/* do_brk() must return target values and target errnos. */
abi_long do_brk(abi_ulong brk_val)
{
abi_long mapped_addr;
- abi_ulong new_alloc_size;
- abi_ulong new_brk, new_host_brk_page;
+ abi_ulong new_brk;
+ abi_ulong old_brk;
/* brk pointers are always untagged */
- /* return old brk value if brk_val unchanged */
- if (brk_val == target_brk) {
- return target_brk;
- }
-
/* do not allow to shrink below initial brk value */
if (brk_val < initial_target_brk) {
return target_brk;
}
new_brk = TARGET_PAGE_ALIGN(brk_val);
- new_host_brk_page = HOST_PAGE_ALIGN(brk_val);
+ old_brk = TARGET_PAGE_ALIGN(target_brk);
- /* brk_val and old target_brk might be on the same page */
- if (new_brk == TARGET_PAGE_ALIGN(target_brk)) {
- /* empty remaining bytes in (possibly larger) host page */
- memset(g2h_untagged(new_brk), 0, new_host_brk_page - new_brk);
+ /* new and old target_brk might be on the same page */
+ if (new_brk == old_brk) {
target_brk = brk_val;
return target_brk;
}
/* Release heap if necesary */
- if (new_brk < target_brk) {
- /* empty remaining bytes in (possibly larger) host page */
- memset(g2h_untagged(new_brk), 0, new_host_brk_page - new_brk);
-
- /* free unused host pages and set new brk_page */
- target_munmap(new_host_brk_page, brk_page - new_host_brk_page);
- brk_page = new_host_brk_page;
+ if (new_brk < old_brk) {
+ target_munmap(new_brk, old_brk - new_brk);
target_brk = brk_val;
return target_brk;
}
- if (new_host_brk_page > brk_page) {
- new_alloc_size = new_host_brk_page - brk_page;
- mapped_addr = target_mmap(brk_page, new_alloc_size,
- PROT_READ | PROT_WRITE,
- MAP_FIXED_NOREPLACE | MAP_ANON | MAP_PRIVATE,
- -1, 0);
- } else {
- new_alloc_size = 0;
- mapped_addr = brk_page;
- }
-
- if (mapped_addr == brk_page) {
- /* Heap contents are initialized to zero, as for anonymous
- * mapped pages. Technically the new pages are already
- * initialized to zero since they *are* anonymous mapped
- * pages, however we have to take care with the contents that
- * come from the remaining part of the previous page: it may
- * contains garbage data due to a previous heap usage (grown
- * then shrunken). */
- memset(g2h_untagged(brk_page), 0, HOST_PAGE_ALIGN(brk_page) - brk_page);
+ mapped_addr = target_mmap(old_brk, new_brk - old_brk,
+ PROT_READ | PROT_WRITE,
+ MAP_FIXED_NOREPLACE | MAP_ANON | MAP_PRIVATE,
+ -1, 0);
+ if (mapped_addr == old_brk) {
target_brk = brk_val;
- brk_page = new_host_brk_page;
return target_brk;
}