flat assembler
Message board for the users of flat assembler.

Index > Unix > to report malloc bug in fasmg on macOS

Author
Thread Post new topic Reply to topic
Melissa



Joined: 12 Apr 2012
Posts: 125
Melissa
Latest Monterey beta causes bug in fasmg x64:
bmaxa@Branimirs-Air asmFish % fasmg "x86/fish.asm" "asmfish" -e 100 -i "VERSION_OS='X'" -i "VERSION_POST = 'popcnt'"
Error: not enough memory to complete the assembly.

but:
Code:
bmaxa@Branimirs-Air memtest % cat mem.c
#include <stdlib.h>
#include <stdio.h>

int main(void) {
  for (long int i=4096;;i*=2){
    void *p = malloc(i);
    if (p)free(p);
    else {
      printf("max %ld\n", i);
      break;
    }
  }
}
    

bmaxa@Branimirs-Air memtest % ./mem
max 140737488355328
bmaxa@Branimirs-Air memtest % symbols mem
mem [arm64, 0.250362 seconds]:
9599C034-0152-3550-9A7F-01E288534647 /Users/bmaxa/projects/memtest/mem [AOUT, PIE, FaultedFromDisk, MMap64]
0x0000000000000000 (0x100000000) __PAGEZERO SEGMENT
0x0000000100000000 ( 0x4000) __TEXT SEGMENT
0x0000000100000000 ( 0x3ed8) MACH_HEADER
0x0000000100003ed8 ( 0x74) __TEXT __text
0x0000000100003ed8 ( 0x74) main [FUNC, EXT, NameNList, MangledNameNList, Merged, NList, FunctionStarts]
0x0000000100003f4c ( 0x24) __TEXT __stubs
0x0000000100003f4c ( 0xc) DYLD-STUB$$free [DYLD-STUB, LENGTH, NameNList, MangledNameNList, NList]
0x0000000100003f58 ( 0xc) DYLD-STUB$$malloc [DYLD-STUB, LENGTH, NameNList, MangledNameNList, NList]
0x0000000100003f64 ( 0xc) DYLD-STUB$$printf [DYLD-STUB, LENGTH, NameNList, MangledNameNList, NList]
0x0000000100003f70 ( 0x3c) __TEXT __stub_helper
0x0000000100003fac ( 0x9) __TEXT __cstring
0x0000000100003fb8 ( 0x48) __TEXT __unwind_info
0x0000000100004000 ( 0x4000) __DATA_CONST SEGMENT
0x0000000100004000 ( 0x8) __DATA_CONST __got
0x0000000100008000 ( 0x4000) __DATA SEGMENT
0x0000000100008000 ( 0x18) __DATA __la_symbol_ptr
0x0000000100008018 ( 0x8) __DATA __data
0x0000000100008018 ( 0x8) _dyld_private [NameNList, MangledNameNList, NList]
0x000000010000c000 ( 0x4000) __LINKEDIT SEGMENT

so I guess it calls wrong version of malloc, or somehow goes beyond limit.
Macbook Air 13" M1 processor.
Post 18 Sep 2021, 08:04
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7958
Location: Kraków, Poland
Tomasz Grysztar
This most likely means that it was not able to get an allocation in 32-bit addressable space, because this is what it needs to function.
Post 18 Sep 2021, 08:08
View user's profile Send private message Visit poster's website Reply with quote
Melissa



Joined: 12 Apr 2012
Posts: 125
Melissa
Tomasz Grysztar wrote:
This most likely means that it was not able to get an allocation in 32-bit addressable space, because this is what it needs to function.


Worked before on earlier beta versions, should I report this to Apple?

edit:
reported, it is their problem, as it worked before
Post 18 Sep 2021, 08:18
View user's profile Send private message Reply with quote
Melissa



Joined: 12 Apr 2012
Posts: 125
Melissa
reply from Apple:
Quote:

After reviewing your feedback, we have some additional information for you, or some additional information, or action is necessary for this issue:

We make no guarantee that returned addresses will fit in 32-bit space. If fasmg can't handle that, it needs to change.

All in all I will start to work on translation to aarch64, so it will be covered, no worry Razz
Post 04 Nov 2021, 12:15
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7958
Location: Kraków, Poland
Tomasz Grysztar
I came up with a new possible solution for the cases when malloc refuses to return memory in 32-bit space. I have already applied it to the x64 Linux version of fasmg - I switched to my own implementation of malloc for fasmg (originally written for the purpose of porting to KolibriOS and DOS), which in turn uses valloc to request larger blocks of memory from OS interface.

The x64 Linux implementation of valloc uses sys_mmap, hoping that either the MAP_32BIT flag or address hint are going to be respected:
Code:
valloc:
; in: ecx = requested minimum size
; out: eax - allocated block, ecx = allocated size, zero if failed
; preserves: ebx, esi, edi
        cmp     ecx,VALLOC_MINIMUM_SIZE
        jbe     valloc_size_minimum
        dec     ecx
        and     ecx,(-1) shl 12
        add     ecx,1 shl 12
        jmp     valloc_size_ready
    valloc_size_minimum:
        mov     ecx,VALLOC_MINIMUM_SIZE
    valloc_size_ready:
        push    rbx rsi rdi
        cmp     [local_heap_available],0
        je      valloc_mmap
        cmp     ecx,LOCAL_HEAP_SIZE
        ja      valloc_mmap
        and     [local_heap_available],0
        mov     eax,local_heap
        mov     ecx,LOCAL_HEAP_SIZE
        jmp     valloc_ok
    valloc_mmap:
        xor     r9d,r9d
        or      r8,-1
        mov     r10d,62h                ; MAP_PRIVATE + MAP_ANONYMOUS + MAP_32BIT
        mov     edx,3                   ; PROT_READ + PROT_WRITE
        mov     esi,ecx
        xor     edi,edi
        mov     eax,9                   ; sys_mmap
        syscall
        cmp     eax,-1
        je      valloc_mmap_with_hint
        mov     ecx,eax
        cmp     rcx,rax
        jne     valloc_mmap_unusable
        add     ecx,esi
        jnc     mmap_ok
    valloc_mmap_unusable:
        mov     rdi,rax
        mov     eax,11                  ; sys_munmap
        syscall
    valloc_mmap_with_hint:
        mov     r10d,22h                ; MAP_PRIVATE + MAP_ANONYMOUS
        mov     edx,3                   ; PROT_READ + PROT_WRITE
        mov     edi,[mmap_hint]
        mov     eax,9                   ; sys_mmap
        syscall
        cmp     eax,-1
        je      valloc_failed
        mov     ecx,eax
        cmp     rcx,rax
        jne     valloc_failed
        add     ecx,esi
        jc      valloc_failed
    mmap_ok:
        sub     ecx,eax
    valloc_ok:
        lea     edx,[eax+ecx]
        mov     [mmap_hint],edx
        pop     rdi rsi rbx
        retn
    valloc_failed:
        xor     ecx,ecx
        pop     rdi rsi rbx
        retn    
But it has an additional protection built-in - even if sys_mmap would be unwilling to cooperate, initially it can use the fixed heap defined in the BSS section:
Code:
segment readable writeable

  align 1000h

  LOCAL_HEAP_SIZE = 1000000h

  local_heap rb LOCAL_HEAP_SIZE    
This is guaranteed to be in 32-bit memory space simply because the program is not PIE, so the segment has a fixed address. And 16 MB heap is enough for fasmg self-hosting, so even in the worst case it would be at least possible for fasmg to reassemble itself with larger heap.

I believe the same trick could be used for other systems, but I would need some testers. Can you help?
Post 31 Dec 2021, 17:22
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.