Introduction into Linux development.

This file is not a proper HOWTO, it just has some notes about learning programming from scratch.

This is even less of a HOWTO, because rather than teaching stuff, it is mostly just guiding the reader over the existing islands of knowledge.

This HOWTO is written with the following goals in mind:

  1. Let the reader as quickly as possible be able to start developing for Android.
  2. PROFIT

1. TODO Body

1.1. Overview

Linux is a kernel, and it runs binary files.

Its binary files are mostly ELF files, “executable-linkable format” files. The spec for ELF files is available from the Linux Foundation website https://refspecs.linuxfoundation.org/elf/elf.pdf#page=9.39 .

The description is easier than it seems.

But if you get lost, there are more human-readable HOWTOs:

  1. Learning Linux Binary Analysis by Ryan “elfmaster” O’Neill, Chapter 2
  2. https://blog.k3170makan.com/2018/09/introduction-to-elf-format-elf-header.html
  3. https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
  4. https://thinkingeek.com/categories/aarch64/

ELF files are characterised by a header and a footer, and the amazing thing is, you can parse the header by just doing a read() into a Elf64_Ehdr* pointer.

I kid you not.

1.2. Using GNU as

“as” is not an English preposition, it is a proper name for GNU assembler.

It has such an amazing documentation, that it is completely impossible to learn it without a supplementary documentation which explains how to read its documentation.

Let have a look.

1.2.1. -a option

-a option helps debugging assembly code. Instead of the binary, it is doing some kind of internal expansion, and shows what exactly it is going to compile.

Generally, it is a bad practice, because you cannot guarantee that it is true. The only way to obtain a true disassembly output is to disassemble the binary.

        .arch armv8-a
        .text
        .globl _start
_start:
        b call_nanosleep

arg1:
        .byte 10
        .rept 15
        .byte 0
        .endr

call_nanosleep:
        adr x0, arg1
        mov x1, 0
        mov     x8, 101         /* write is syscall #64 */
        svc     0               /* invoke syscall */

prg_exit:
        mov     x0, 0           /* status -> 0 */
        mov     x8, 93          /* exit is syscall #93 */
        svc     0               /* invoke scallop */

As we can see, the default as -a output includes pagination by default. (Господи, ну что за хуйня, как так можно вообще…🤦‍♂️)

1.2.2. -R option

This option removed .data section generation, and places all data into .text.

        .arch armv8-a
        .text
        .globl _start
_start:
        b call_nanosleep

arg1:
        .byte 10
        .rept 15
        .byte 0
        .endr

call_nanosleep:
        adr x0, arg1
        mov x1, 0
        mov     x8, 101         /* write is syscall #64 */
        svc     0               /* invoke syscall */

prg_exit:
        mov     x0, 0           /* status -> 0 */
        mov     x8, 93          /* exit is syscall #93 */
        svc     0               /* invoke scallop */

1.2.3. Preprocessing

You can use the gnu C compiler driver to get other “CPP” style preprocessing by giving the input file a ‘.S’ suffix

Hm… sounds crazy?

        .arch armv8-a
        .text
        .globl _start
_start:
        b call_nanosleep

arg1:
        .byte 10
        .rept 15
        .byte 0
        .endr

call_nanosleep:
        adr x0, arg1
        mov x1, 0
        mov     x8, 101         /* write is syscall #64 */
        svc     0               /* invoke syscall */

prg_exit:
        mov     x0, 0           /* status -> 0 */
        mov     x8, 93          /* exit is syscall #93 */
        svc     0               /* invoke scallop */