Fix brk system call.
authorMichael Meissner <gnu@the-meissners.org>
Wed, 6 Sep 1995 14:00:16 +0000 (14:00 +0000)
committerMichael Meissner <gnu@the-meissners.org>
Wed, 6 Sep 1995 14:00:16 +0000 (14:00 +0000)
sim/ppc/core.c
sim/ppc/system.c

index 5e8479fcf832bcea0e1f5c5c9a59b47be1b20164..9c47a6ce8a0889cb2a3a33878c2ea65fca0d35d1 100644 (file)
@@ -312,24 +312,47 @@ core_stack_size(core *memory)
 INLINE_CORE void 
 core_add_data(core *memory, unsigned_word incr)
 {
-  memory->data_upper_bound += incr;
-  if (memory->data_upper_bound > memory->data_high_water) {
-    malloc_core_memory(memory, memory->data_high_water, incr,
-                    device_is_readable | device_is_writeable);
-    memory->data_high_water = memory->data_upper_bound;
+  unsigned_word new_upper_bound = memory->data_upper_bound + incr;
+  if (new_upper_bound > memory->data_high_water) {
+    if (memory->data_upper_bound >= memory->data_high_water)
+      /* all the memory is new */
+      malloc_core_memory(memory,
+                        memory->data_upper_bound,
+                        incr,
+                        device_is_readable | device_is_writeable);
+    else
+      /* some of the memory was already allocated, only need to add
+         missing bit */
+      malloc_core_memory(memory,
+                        memory->data_high_water,
+                        new_upper_bound - memory->data_high_water,
+                        device_is_readable | device_is_writeable);
+    memory->data_high_water = new_upper_bound;
   }
+  memory->data_upper_bound = new_upper_bound;
 }
 
 
 INLINE_CORE void 
 core_add_stack(core *memory, unsigned_word incr)
 {
-  memory->stack_lower_bound -= incr;
-  if (memory->stack_lower_bound < memory->stack_low_water) {
-    malloc_core_memory(memory, memory->stack_lower_bound, incr,
-                      device_is_readable | device_is_writeable);
-    memory->stack_low_water = memory->stack_lower_bound;
+  unsigned_word new_lower_bound = memory->stack_lower_bound - incr;
+  if (new_lower_bound < memory->stack_low_water) {
+    if (memory->stack_lower_bound <= memory->stack_low_water)
+      /* all the memory is new */
+      malloc_core_memory(memory,
+                        new_lower_bound,
+                        incr,
+                        device_is_readable | device_is_writeable);
+    else
+      /* allocate only the extra bit */
+      malloc_core_memory(memory,
+                        new_lower_bound, 
+                        memory->stack_low_water - new_lower_bound,
+                        device_is_readable | device_is_writeable);
+    memory->stack_low_water = new_lower_bound;
   }
+  memory->stack_lower_bound = new_lower_bound;
 }
 
 
index ca62b27ba52a2b065d00f8f9139c1fdf80a2fd4f..c032688bebad7412d91a989315f2a603612d8e24 100644 (file)
@@ -169,13 +169,17 @@ system_call(cpu *processor,
 #  error "SYS_break"
 #endif
     {
-      unsigned_word new_sbrk = ALIGN_PAGE(cpu_registers(processor)->gpr[3]);
-      unsigned_word old_sbrk = core_data_upper_bound(cpu_core(processor));
-      signed_word delta = new_sbrk - old_sbrk;
+      /* pretend to extend the heap so that it reaches addresss
+         new_break while in truth, if growth is needed grow it by a
+         page aligned amount */
+      unsigned_word new_break = ALIGN_8(cpu_registers(processor)->gpr[3]);
+      unsigned_word old_break = core_data_upper_bound(cpu_core(processor));
+      signed_word delta = new_break - old_break;
       if (delta > 0)
-       core_add_data(cpu_core(processor), delta);
+       core_add_data(cpu_core(processor),
+                     ALIGN_PAGE(new_break) - old_break);
       cpu_registers(processor)->gpr[0] = 0;
-      cpu_registers(processor)->gpr[3] = new_sbrk;
+      cpu_registers(processor)->gpr[3] = new_break;
       break;
     }