Mam ten program ARM64, który montuje się, ale Segfaults natychmiast po uruchomieniu:

// GNU Assembler, ARM64 Linux

.bss

.lcomm ARRAY, 16

.text

.global _start

_start:
    mov x8, 93 // exit sys num
    mov x0, 0 // success
    svc 0

Od Brute-Force Trial i błąd Udało mi się naprawić, dodając tę linię:

// GNU Assembler, ARM64 Linux

.bss

.lcomm ARRAY, 16

.p2align 12 // why?

.text

.global _start

_start:
    mov x8, 93 // exit sys num
    mov x0, 0 // success
    svc 0

Działa tylko z .p2align 12 (odpowiednik .balign 4096) lub wyższa, w przeciwnym razie nadal jest segfaults z wartościami .p2align 11 lub niższej. Rozumiem, że wyściółka prawdopodobnie ustalająca pewną kwestię niewspółosiowości, ale nie rozumiem, dlaczego musi to być taka duża wartość, jak praktycznie każdy przykład arm64, jaki widziałem, zarówno napisane ręcznie, jak i produkowane przez kompilatory, zwykle wkłada tylko a .p2align 2 Przed sekcją .text Dlaczego więc potrzebuję .p2align 12 dla mojego małego programu?

Ponadto zauważyłem wymagany rozmiar wyściółki, jest odwrotnie - proporcjonalny do długości sekcji {X0}}. W przypadku małych programów, takich jak .p2align 12, jest wymagane, aby uruchamiać się bez segacji, jednak dłużej sekcja .text staje się mniejsza, którą mogę wykonać wyściółkę oraz programy, które mają tysiące instrukcji, które nie Musi dodać dowolne wyściółki!

Jestem na maszynie MacoS X86_64, ale kompilacja i prowadzę te programy wewnątrz zbiornika dokującego, który jest zbudowany z tego Dockerfile:

FROM ubuntu:20.04
RUN apt-get update && apt-get -y install clang qemu gcc-aarch64-linux-gnu

Komppracuję i prowadzę programy Arm64 z:

clang -nostdlib -fno-integrated-as -target aarch64-linux-gnu -s program.s -o program.out && ./program.out

Czuję, że brakuje mi niektórych kluczowych informacji dotyczących gazu, QEMU, ARM64 lub Executables Elf, ale nie mam pojęcia, co to jest.

2
pretzelhammer 22 listopad 2020, 19:02

1 odpowiedź

Najlepsza odpowiedź

QEMU jest zdezorientowany przez nagłówek programu do sekcji danych:

    LOAD off    0x00000000000000c0 vaddr 0x00000000004100c0 paddr 0x00000000004100c0 align 2**16
         filesz 0x0000000000000000 memsz 0x0000000000000010 flags rw-

I nie może faktycznie mmap pamięci do pisania na tym adresie; Segfault pochodzą z samego Qemu, gdy próbuje memset () BSS do zera.

Ponieważ program działa dobrze na prawdziwym jądrze AARCH64 Linux, jest to błąd qemu. Zgłoszono to do listy mailingowej Upstream, więc zobaczymy, czy ktoś wymyślił.

1
Peter Maydell 23 listopad 2020, 21:01