From e829231328467b6842774c1a0dbc16ba42f28291 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Mon, 19 Dec 2022 15:59:08 +0400 Subject: [PATCH 1/2] Print Multiboot 2 ELF section headers (#154) --- ChangeLog | 4 + fixtures/multiboot2_info_example1.txt | 147 ++++++++++++++++++- fixtures/multiboot2_info_example2.txt | 147 ++++++++++++++++++- include/kernaux/elf.h | 202 ++++++++++++++++++-------- include/kernaux/multiboot2.h | 2 +- src/elf.c | 87 +++++------ src/multiboot2/header_print.c | 34 +++-- src/multiboot2/info_print.c | 191 +++++++++++++++++++++--- tests/test_elf.c | 23 +-- 9 files changed, 660 insertions(+), 177 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6c0267a2..84faee21 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2022-12-19 Alex Kotov + + * src/multiboot2/*_print.c: Print Multiboot 2 ELF section headers + 2022-12-17 Alex Kotov * configure.ac: Feature "--(enable|disable)-fixtures" has been added diff --git a/fixtures/multiboot2_info_example1.txt b/fixtures/multiboot2_info_example1.txt index 93efa0e0..3d73f613 100644 --- a/fixtures/multiboot2_info_example1.txt +++ b/fixtures/multiboot2_info_example1.txt @@ -50,37 +50,37 @@ Multiboot 2 info tag { u32 entry_size: 24 u32 entry_version: 0 varies(entry_size) entries[]: [ - [0] entry: { + [0]: { u64 base_addr: 0x0 u64 length: 654336 u32 type: 1 u32 reserved: 0x0 } - [1] entry: { + [1]: { u64 base_addr: 0x9fc00 u64 length: 1024 u32 type: 2 u32 reserved: 0x0 } - [2] entry: { + [2]: { u64 base_addr: 0xf0000 u64 length: 65536 u32 type: 2 u32 reserved: 0x0 } - [3] entry: { + [3]: { u64 base_addr: 0x100000 u64 length: 133038080 u32 type: 1 u32 reserved: 0x0 } - [4] entry: { + [4]: { u64 base_addr: 0x7fe0000 u64 length: 131072 u32 type: 2 u32 reserved: 0x0 } - [5] entry: { + [5]: { u64 base_addr: 0xfffc0000 u64 length: 262144 u32 type: 2 @@ -94,6 +94,141 @@ Multiboot 2 info tag { u32 num: 10 u32 entsize: 40 u32 shndx: 9 + varies(entsize) section_headers[]: [ + [0]: { + name: 0 + type: 0 (NULL) + flags: 0x0 () + addr: 0x0 + offset: 0x0 + size: 0 + link: 0 + info: 0 + addralign: 0 + entsize: 0 + } + [1]: { + name: 27 + type: 1 (PROGBITS) + flags: 0x6 ( + ALLOC | + EXECINSTR + ) + addr: 0x400000 + offset: 0x1000 + size: 13718 + link: 0 + info: 0 + addralign: 4096 + entsize: 0 + } + [2]: { + name: 33 + type: 1 (PROGBITS) + flags: 0x2 ( + ALLOC + ) + addr: 0x404000 + offset: 0x5000 + size: 2824 + link: 0 + info: 0 + addralign: 4096 + entsize: 0 + } + [3]: { + name: 41 + type: 1 (PROGBITS) + flags: 0x2 ( + ALLOC + ) + addr: 0x404b08 + offset: 0x5b08 + size: 2692 + link: 0 + info: 0 + addralign: 4 + entsize: 0 + } + [4]: { + name: 51 + type: 1 (PROGBITS) + flags: 0x3 ( + WRITE | + ALLOC + ) + addr: 0x406000 + offset: 0x7000 + size: 1 + link: 0 + info: 0 + addralign: 4096 + entsize: 0 + } + [5]: { + name: 57 + type: 8 (NOBITS) + flags: 0x3 ( + WRITE | + ALLOC + ) + addr: 0x407000 + offset: 0x7001 + size: 43328 + link: 0 + info: 0 + addralign: 4096 + entsize: 0 + } + [6]: { + name: 62 + type: 1 (PROGBITS) + flags: 0x30 () + addr: 0x100000 + offset: 0x7001 + size: 17 + link: 0 + info: 0 + addralign: 1 + entsize: 1 + } + [7]: { + name: 1 + type: 2 (SYMTAB) + flags: 0x0 () + addr: 0x100014 + offset: 0x7014 + size: 3248 + link: 8 + info: 72 + addralign: 4 + entsize: 16 + } + [8]: { + name: 9 + type: 3 (STRTAB) + flags: 0x0 () + addr: 0x100cc4 + offset: 0x7cc4 + size: 3536 + link: 0 + info: 0 + addralign: 1 + entsize: 0 + } + [9]: { + name: 17 + type: 3 (STRTAB) + flags: 0x0 () + addr: 0x101a94 + offset: 0x8a94 + size: 71 + link: 0 + info: 0 + addralign: 1 + entsize: 0 + } + ] } Multiboot 2 info tag { u32 type: 4 (basic memory info) diff --git a/fixtures/multiboot2_info_example2.txt b/fixtures/multiboot2_info_example2.txt index 6ac5c405..d32769c5 100644 --- a/fixtures/multiboot2_info_example2.txt +++ b/fixtures/multiboot2_info_example2.txt @@ -45,37 +45,37 @@ Multiboot 2 info tag { u32 entry_size: 24 u32 entry_version: 0 varies(entry_size) entries[]: [ - [0] entry: { + [0]: { u64 base_addr: 0x0 u64 length: 654336 u32 type: 1 u32 reserved: 0x0 } - [1] entry: { + [1]: { u64 base_addr: 0x9fc00 u64 length: 1024 u32 type: 2 u32 reserved: 0x0 } - [2] entry: { + [2]: { u64 base_addr: 0xf0000 u64 length: 65536 u32 type: 2 u32 reserved: 0x0 } - [3] entry: { + [3]: { u64 base_addr: 0x100000 u64 length: 133038080 u32 type: 1 u32 reserved: 0x0 } - [4] entry: { + [4]: { u64 base_addr: 0x7fe0000 u64 length: 131072 u32 type: 2 u32 reserved: 0x0 } - [5] entry: { + [5]: { u64 base_addr: 0xfffc0000 u64 length: 262144 u32 type: 2 @@ -160,6 +160,141 @@ Multiboot 2 info tag { u32 num: 10 u32 entsize: 40 u32 shndx: 9 + varies(entsize) section_headers[]: [ + [0]: { + name: 0 + type: 0 (NULL) + flags: 0x0 () + addr: 0x0 + offset: 0x0 + size: 0 + link: 0 + info: 0 + addralign: 0 + entsize: 0 + } + [1]: { + name: 27 + type: 1 (PROGBITS) + flags: 0x6 ( + ALLOC | + EXECINSTR + ) + addr: 0x400000 + offset: 0x1000 + size: 13718 + link: 0 + info: 0 + addralign: 4096 + entsize: 0 + } + [2]: { + name: 33 + type: 1 (PROGBITS) + flags: 0x2 ( + ALLOC + ) + addr: 0x404000 + offset: 0x5000 + size: 2824 + link: 0 + info: 0 + addralign: 4096 + entsize: 0 + } + [3]: { + name: 41 + type: 1 (PROGBITS) + flags: 0x2 ( + ALLOC + ) + addr: 0x404b08 + offset: 0x5b08 + size: 2692 + link: 0 + info: 0 + addralign: 4 + entsize: 0 + } + [4]: { + name: 51 + type: 1 (PROGBITS) + flags: 0x3 ( + WRITE | + ALLOC + ) + addr: 0x406000 + offset: 0x7000 + size: 1 + link: 0 + info: 0 + addralign: 4096 + entsize: 0 + } + [5]: { + name: 57 + type: 8 (NOBITS) + flags: 0x3 ( + WRITE | + ALLOC + ) + addr: 0x407000 + offset: 0x7001 + size: 43328 + link: 0 + info: 0 + addralign: 4096 + entsize: 0 + } + [6]: { + name: 62 + type: 1 (PROGBITS) + flags: 0x30 () + addr: 0x100000 + offset: 0x7001 + size: 17 + link: 0 + info: 0 + addralign: 1 + entsize: 1 + } + [7]: { + name: 1 + type: 2 (SYMTAB) + flags: 0x0 () + addr: 0x100014 + offset: 0x7014 + size: 3248 + link: 8 + info: 72 + addralign: 4 + entsize: 16 + } + [8]: { + name: 9 + type: 3 (STRTAB) + flags: 0x0 () + addr: 0x100cc4 + offset: 0x7cc4 + size: 3536 + link: 0 + info: 0 + addralign: 1 + entsize: 0 + } + [9]: { + name: 17 + type: 3 (STRTAB) + flags: 0x0 () + addr: 0x101a94 + offset: 0x8a94 + size: 71 + link: 0 + info: 0 + addralign: 1 + entsize: 0 + } + ] } Multiboot 2 info tag { u32 type: 10 (APM table) diff --git a/include/kernaux/elf.h b/include/kernaux/elf.h index 5fde2266..793cdc31 100644 --- a/include/kernaux/elf.h +++ b/include/kernaux/elf.h @@ -7,87 +7,173 @@ extern "C" { #include -#include +#include #include +struct KernAux_ELF_Ident { + uint8_t magic_0x7f; + uint8_t magic_E; + uint8_t magic_L; + uint8_t magic_F; + uint8_t class_; + uint8_t data; + uint8_t version; + uint8_t unused[9]; +} +KERNAUX_PACKED; + +KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_ELF_Ident, 16); + +// KernAux_ELF_Ident.class_ +#define KERNAUX_ELF_CLASS_NONE 0 // Invalid class +#define KERNAUX_ELF_CLASS_32 1 // 32-bit objects +#define KERNAUX_ELF_CLASS_64 2 // 64-bit objects + +// KernAux_ELF_Ident.data +#define KERNAUX_ELF_DATA_NONE 0 // Invalid data encoding +#define KERNAUX_ELF_DATA_2LSB 1 // 0x01020304 == [0x04, 0x03, 0x02, 0x01] +#define KERNAUX_ELF_DATA_2MSB 2 // 0x01020304 == [0x01, 0x02, 0x03, 0x04] + struct KernAux_ELF_Header { - unsigned magic_0x7f : 8; - unsigned magic_E : 8; - unsigned magic_L : 8; - unsigned magic_F : 8; - unsigned bitness : 8; - unsigned endianness : 8; - unsigned header_version : 8; - unsigned os_abi : 8; - unsigned unused1 : 32; - unsigned unused2 : 32; - unsigned obj_type : 16; - unsigned isa : 16; - unsigned elf_version : 32; - unsigned entrypoint : 32; - unsigned prog_table_pos : 32; - unsigned sect_table_pos : 32; - unsigned arch_flags : 32; - unsigned header_size : 16; - unsigned prog_entr_size : 16; - unsigned prog_entr_num : 16; - unsigned sect_entr_size : 16; - unsigned sect_entr_num : 16; - unsigned sect_names_idx : 16; + struct KernAux_ELF_Ident ident; + uint16_t type; + uint16_t machine; + uint32_t version; + uint32_t entry; + uint32_t phoff; + uint32_t shoff; + uint32_t flags; + uint16_t ehsize; + uint16_t phentsize; + uint16_t phnum; + uint16_t shentsize; + uint16_t shnum; + uint16_t shstrndx; } KERNAUX_PACKED; KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_ELF_Header, 52); -struct KernAux_ELF_ProgramEntry { - unsigned type : 32; - unsigned offset : 32; - unsigned virt_addr : 32; - unsigned phys_addr : 32; - unsigned file_size : 32; - unsigned mem_size : 32; - unsigned flags : 32; - unsigned align : 32; +// KernAux_ELF_Header.type +#define KERNAUX_ELF_TYPE_NONE 0 // No file type +#define KERNAUX_ELF_TYPE_REL 1 // Relocatable file +#define KERNAUX_ELF_TYPE_EXEC 2 // Executable file +#define KERNAUX_ELF_TYPE_DYN 3 // Shared object file +#define KERNAUX_ELF_TYPE_CORE 4 // Core file +#define KERNAUX_ELF_TYPE_LOPROC 0xff00 // Processor-specific +#define KERNAUX_ELF_TYPE_HIPROC 0xffff // Processor-specific + +// KernAux_ELF_Header.machine +#define KERNAUX_ELF_MACHINE_NONE 0 // No machine +#define KERNAUX_ELF_MACHINE_M32 1 // AT&T WE 32100 +#define KERNAUX_ELF_MACHINE_SPARC 2 // SPARC +#define KERNAUX_ELF_MACHINE_386 3 // Intel 80386 +#define KERNAUX_ELF_MACHINE_68K 4 // Motorola 68000 +#define KERNAUX_ELF_MACHINE_88K 5 // Motorola 88000 +#define KERNAUX_ELF_MACHINE_860 7 // Intel 80860 +#define KERNAUX_ELF_MACHINE_MIPS 8 // MIPS RS3000 + +// KernAux_ELF_Header.version +#define KERNAUX_ELF_VERSION_NONE 0 // Invalid version +#define KERNAUX_ELF_VERSION_CURRENT 1 // Current version + +struct KernAux_ELF_Section { + uint32_t name; + uint32_t type; + uint32_t flags; + uint32_t addr; + uint32_t offset; + uint32_t size; + uint32_t link; + uint32_t info; + uint32_t addralign; + uint32_t entsize; } KERNAUX_PACKED; -KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_ELF_ProgramEntry, 32); +KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_ELF_Section, 40); -struct KernAux_ELF_SectionEntry { - unsigned name : 32; - unsigned type : 32; - unsigned flags : 32; - unsigned vaddr : 32; - unsigned file_offset : 32; - unsigned file_size : 32; - unsigned link : 32; - unsigned info : 32; - unsigned alignment : 32; - unsigned ent_size : 32; +#define KERNAUX_ELF_SECT_TYPE_NULL 0 +#define KERNAUX_ELF_SECT_TYPE_PROGBITS 1 +#define KERNAUX_ELF_SECT_TYPE_SYMTAB 2 +#define KERNAUX_ELF_SECT_TYPE_STRTAB 3 +#define KERNAUX_ELF_SECT_TYPE_RELA 4 +#define KERNAUX_ELF_SECT_TYPE_HASH 5 +#define KERNAUX_ELF_SECT_TYPE_DYNAMIC 6 +#define KERNAUX_ELF_SECT_TYPE_NOTE 7 +#define KERNAUX_ELF_SECT_TYPE_NOBITS 8 +#define KERNAUX_ELF_SECT_TYPE_REL 9 +#define KERNAUX_ELF_SECT_TYPE_SHLIB 10 +#define KERNAUX_ELF_SECT_TYPE_DYNSYM 11 +#define KERNAUX_ELF_SECT_TYPE_LOPROC 0x70000000 +#define KERNAUX_ELF_SECT_TYPE_HIPROC 0x7fffffff +#define KERNAUX_ELF_SECT_TYPE_LOUSER 0x80000000 +#define KERNAUX_ELF_SECT_TYPE_HIUSER 0xffffffff + +#define KERNAUX_ELF_SECT_FLAGS_WRITE 0x1 +#define KERNAUX_ELF_SECT_FLAGS_ALLOC 0x2 +#define KERNAUX_ELF_SECT_FLAGS_EXECINSTR 0x4 +#define KERNAUX_ELF_SECT_FLAGS_MASKPROC 0xf0000000 + +const char *KernAux_ELF_Section_Type_to_str(uint32_t type); + +struct KernAux_ELF_Symbol { + uint32_t name; + uint32_t value; + uint32_t size; + uint8_t info; + uint8_t other; + uint16_t shndx; } KERNAUX_PACKED; -KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_ELF_SectionEntry, 40); +KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_ELF_Symbol, 16); -struct KernAux_ELF_RelocationEntry { - unsigned virt_addr : 32; - unsigned info : 32; +#define KERNAUX_ELF_SYM_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) +#define KERNAUX_ELF_SYM_BIND(info) ((info) >> 4) +#define KERNAUX_ELF_SYM_TYPE(info) ((into) & 0xf) + +#define KERNAUX_ELF_SYM_BIND_LOCAL 0 +#define KERNAUX_ELF_SYM_BIND_GLOBAL 1 +#define KERNAUX_ELF_SYM_BIND_WEAK 2 +#define KERNAUX_ELF_SYM_BIND_LOPROC 13 +#define KERNAUX_ELF_SYM_BIND_HIPROC 15 + +#define KERNAUX_ELF_SYM_TYPE_NOTYPE 0 +#define KERNAUX_ELF_SYM_TYPE_OBJECT 1 +#define KERNAUX_ELF_SYM_TYPE_FUNC 2 +#define KERNAUX_ELF_SYM_TYPE_SECTION 3 +#define KERNAUX_ELF_SYM_TYPE_FILE 4 +#define KERNAUX_ELF_SYM_TYPE_LOPROC 13 +#define KERNAUX_ELF_SYM_TYPE_HIPROC 15 + +struct KernAux_ELF_Program { + uint32_t type; + uint32_t offset; + uint32_t vaddr; + uint32_t paddr; + uint32_t filesz; + uint32_t memsz; + uint32_t flags; + uint32_t align; } KERNAUX_PACKED; -KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_ELF_RelocationEntry, 8); +KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_ELF_Program, 32); + +#define KERNAUX_ELF_PROG_TYPE_NULL 0 +#define KERNAUX_ELF_PROG_TYPE_LOAD 1 +#define KERNAUX_ELF_PROG_TYPE_DYNAMIC 2 +#define KERNAUX_ELF_PROG_TYPE_INTERP 3 +#define KERNAUX_ELF_PROG_TYPE_NOTE 4 +#define KERNAUX_ELF_PROG_TYPE_SHLIB 5 +#define KERNAUX_ELF_PROG_TYPE_PHDR 6 +#define KERNAUX_ELF_PROG_TYPE_LOPROC 0x70000000 +#define KERNAUX_ELF_PROG_TYPE_HIPROC 0x7fffffff #include -typedef struct KernAux_ELF_ProgramEntry KernAux_ELF_ProgramTable[]; - -typedef struct KernAux_ELF_SectionEntry KernAux_ELF_SectionTable[]; - -typedef struct KernAux_ELF_RelocationEntry KernAux_ELF_RelocationTable[]; - -bool KernAux_ELF_Header_is_valid(const struct KernAux_ELF_Header *header); - #ifdef __cplusplus } #endif diff --git a/include/kernaux/multiboot2.h b/include/kernaux/multiboot2.h index 63d740fd..fbd67a58 100644 --- a/include/kernaux/multiboot2.h +++ b/include/kernaux/multiboot2.h @@ -366,7 +366,7 @@ struct KernAux_Multiboot2_ITag_ELFSymbols { uint32_t entsize; uint32_t shndx; - // DATA: varies section_headers[] + // DATA: varies(entsize) section_headers[] } KERNAUX_PACKED; diff --git a/src/elf.c b/src/elf.c index 95da3cbe..125cbd11 100644 --- a/src/elf.c +++ b/src/elf.c @@ -2,56 +2,47 @@ #include "config.h" #endif -#include #include +#include -bool KernAux_ELF_Header_is_valid( - const struct KernAux_ELF_Header *const header -) { - KERNAUX_ASSERT(header); +#include - if (!( - header->magic_0x7f == 0x7f && - header->magic_E == 'E' && - header->magic_L == 'L' && - header->magic_F == 'F' && - header->header_version == 1 && - header->elf_version == 1 - )) { - return false; +const char *KernAux_ELF_Section_Type_to_str(const uint32_t type) +{ + switch (type) { + case KERNAUX_ELF_SECT_TYPE_NULL: + return "NULL"; + case KERNAUX_ELF_SECT_TYPE_PROGBITS: + return "PROGBITS"; + case KERNAUX_ELF_SECT_TYPE_SYMTAB: + return "SYMTAB"; + case KERNAUX_ELF_SECT_TYPE_STRTAB: + return "STRTAB"; + case KERNAUX_ELF_SECT_TYPE_RELA: + return "RELA"; + case KERNAUX_ELF_SECT_TYPE_HASH: + return "HASH"; + case KERNAUX_ELF_SECT_TYPE_DYNAMIC: + return "DYNAMIC"; + case KERNAUX_ELF_SECT_TYPE_NOTE: + return "NOTE"; + case KERNAUX_ELF_SECT_TYPE_NOBITS: + return "NOBITS"; + case KERNAUX_ELF_SECT_TYPE_REL: + return "REL"; + case KERNAUX_ELF_SECT_TYPE_SHLIB: + return "SHLIB"; + case KERNAUX_ELF_SECT_TYPE_DYNSYM: + return "DYNSYM"; + case KERNAUX_ELF_SECT_TYPE_LOPROC: + return "LOPROC"; + case KERNAUX_ELF_SECT_TYPE_HIPROC: + return "HIPROC"; + case KERNAUX_ELF_SECT_TYPE_LOUSER: + return "LOUSER"; + case KERNAUX_ELF_SECT_TYPE_HIUSER: + return "HIUSER"; + default: + return NULL; } - - if (!( - header->bitness == 1 || // 32 bit - header->bitness == 2 // 64 bit - )) { - return false; - } - - if (!( - header->endianness == 1 || // Little endian - header->endianness == 2 // Big endian - )) { - return false; - } - - if (!(header->os_abi <= 0x12 && header->os_abi != 0x05)) { - return false; - } - - if (!( - header->obj_type == 0x00 || // NONE - header->obj_type == 0x01 || // REL - header->obj_type == 0x02 || // EXEC - header->obj_type == 0x03 || // DYN - header->obj_type == 0x04 || // CORE - header->obj_type == 0xfe00 || // LOOS - header->obj_type == 0xfeff || // HIOS - header->obj_type == 0xff00 || // LOPROC - header->obj_type == 0xffff // HIPROC - )) { - return false; - } - - return true; } diff --git a/src/multiboot2/header_print.c b/src/multiboot2/header_print.c index bffe35fb..f0e95065 100644 --- a/src/multiboot2/header_print.c +++ b/src/multiboot2/header_print.c @@ -225,26 +225,30 @@ void KernAux_Multiboot2_HTag_InfoReq_print( // Print data: - PRINTLN(" u32 mbi_tag_types[]: ["); + if ((tag->base.size - sizeof(*tag)) / sizeof(uint32_t) == 0) { + PRINTLN(" u32 mbi_tag_types[]: []"); + } else { + PRINTLN(" u32 mbi_tag_types[]: ["); - const uint32_t *const mbi_tag_types = - (const uint32_t*)KERNAUX_MULTIBOOT2_DATA(tag); + const uint32_t *const mbi_tag_types = + (const uint32_t*)KERNAUX_MULTIBOOT2_DATA(tag); - for ( - size_t index = 0; - index < (tag->base.size - sizeof(*tag)) / sizeof(uint32_t); - ++index - ) { - KERNAUX_CAST_CONST(unsigned long, type, mbi_tag_types[index]); + for ( + size_t index = 0; + index < (tag->base.size - sizeof(*tag)) / sizeof(uint32_t); + ++index + ) { + KERNAUX_CAST_CONST(unsigned long, type, mbi_tag_types[index]); - PRINTLNF(" %lu (%s)", - type, - KernAux_Multiboot2_ITag_to_str(type) - ); + PRINTLNF(" %lu (%s)", + type, + KernAux_Multiboot2_ITag_to_str(type) + ); + } + + PRINTLN(" ]"); } - PRINTLN(" ]"); - FOOTER; } diff --git a/src/multiboot2/info_print.c b/src/multiboot2/info_print.c index 81b18777..95992757 100644 --- a/src/multiboot2/info_print.c +++ b/src/multiboot2/info_print.c @@ -3,10 +3,12 @@ #endif #include +#include #include #include #include +#include #include #include @@ -39,6 +41,44 @@ #define FOOTER do { PRINTLN("}"); } while (0) +#define INDENT do { \ + for (unsigned index = 0; index < basic_indentation; ++index) PRINT(" "); \ +} while (0) + +#define INDENT_MORE do { \ + for (unsigned index = 0; index < indentation_delta; ++index) PRINT(" "); \ +} while (0) + +static const struct { + uint32_t number; + const char *name; +} section_flag_names[] = { + { + .number = KERNAUX_ELF_SECT_FLAGS_WRITE, + .name = "WRITE", + }, + { + .number = KERNAUX_ELF_SECT_FLAGS_ALLOC, + .name = "ALLOC", + }, + { + .number = KERNAUX_ELF_SECT_FLAGS_EXECINSTR, + .name = "EXECINSTR", + }, + { + .number = KERNAUX_ELF_SECT_FLAGS_MASKPROC, + .name = "MASKPROC", + }, +}; + +static void KernAux_ELF_Section_Flags_print( + uint16_t flags, + KernAux_Display display, + unsigned basic_indentation, + unsigned indentation_delta, + bool indent_first +); + void KernAux_Multiboot2_Info_print( const struct KernAux_Multiboot2_Info *const multiboot2_info, const KernAux_Display display @@ -308,31 +348,43 @@ void KernAux_Multiboot2_ITag_MemoryMap_print( // Print data: - PRINTLN (" varies(entry_size) entries[]: ["); + if (tag->entry_size == 0 || + (tag->base.size - sizeof(*tag)) / tag->entry_size == 0) + { + PRINTLN (" varies(entry_size) entries[]: []"); + } else { + PRINTLN (" varies(entry_size) entries[]: ["); - const struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase *const entries = - (struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase*) - KERNAUX_MULTIBOOT2_DATA((struct KernAux_Multiboot2_ITag_MemoryMap*)tag); + const struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase* + const entries = + (struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase*) + KERNAUX_MULTIBOOT2_DATA(tag); - for ( - size_t index = 0; - index < (tag->base.size - sizeof(*tag)) / tag->entry_size; - ++index - ) { - KERNAUX_CAST_CONST(unsigned long long, base_addr, entries[index].base_addr); - KERNAUX_CAST_CONST(unsigned long long, length, entries[index].length); - KERNAUX_CAST_CONST(unsigned long, type, entries[index].type); - KERNAUX_CAST_CONST(unsigned long, reserved, entries[index].reserved); + for ( + size_t index = 0; + index < (tag->base.size - sizeof(*tag)) / tag->entry_size; + ++index + ) { + KERNAUX_CAST_CONST(unsigned long long, base_addr, + entries[index].base_addr); + KERNAUX_CAST_CONST(unsigned long long, length, + entries[index].length); + KERNAUX_CAST_CONST(unsigned long, type, + entries[index].type); + KERNAUX_CAST_CONST(unsigned long, reserved, + entries[index].reserved); - PRINTLNF(" [%zu] entry: {", index); - PRINTLNF(" u64 base_addr: 0x%llx", base_addr); - PRINTLNF(" u64 length: %llu", length); - PRINTLNF(" u32 type: %lu", type); - PRINTLNF(" u32 reserved: 0x%lx", reserved); - PRINTLN (" }"); + PRINTLNF(" [%zu]: {", index); + PRINTLNF(" u64 base_addr: 0x%llx", base_addr); + PRINTLNF(" u64 length: %llu", length); + PRINTLNF(" u32 type: %lu", type); + PRINTLNF(" u32 reserved: 0x%lx", reserved); + PRINTLN (" }"); + } + + PRINTLN(" ]"); } - PRINTLN(" ]"); FOOTER; } @@ -426,7 +478,62 @@ void KernAux_Multiboot2_ITag_ELFSymbols_print( PRINTLNF(" u32 entsize: %lu", entsize); PRINTLNF(" u32 shndx: %lu", shndx); - // TODO: Print data? + // Print data: + + if (tag->num == 0) { + PRINTLN(" varies(entsize) section_headers[]: []"); + } else { + PRINTLN(" varies(entsize) section_headers[]: ["); + + const struct KernAux_ELF_Section *section = + (const struct KernAux_ELF_Section*) + KERNAUX_MULTIBOOT2_DATA(tag); + + for (size_t index = 0; index < tag->num; ++index) { + KERNAUX_CAST_CONST(unsigned long, name, section->name); + KERNAUX_CAST_CONST(unsigned long, type, section->type); + KERNAUX_CAST_CONST(unsigned long, addr, section->addr); + KERNAUX_CAST_CONST(unsigned long, offset, section->offset); + KERNAUX_CAST_CONST(unsigned long, size, section->size); + KERNAUX_CAST_CONST(unsigned long, link, section->link); + KERNAUX_CAST_CONST(unsigned long, info, section->info); + KERNAUX_CAST_CONST(unsigned long, addralign, section->addralign); + KERNAUX_CAST_CONST(unsigned long, s_entsize, section->entsize); + + const char *const type_name = +#ifdef WITH_ELF + KernAux_ELF_Section_Type_to_str(section->type); +#else + "?"; +#endif + + PRINTLNF(" [%zu]: {", index); + PRINTLNF(" name: %lu", name); + PRINTLNF(" type: %lu (%s)", type, type_name); + PRINT (" flags: "); + KernAux_ELF_Section_Flags_print( + section->flags, + display, + 6, + 2, + false + ); + PRINTLNF(" addr: 0x%lx", addr); + PRINTLNF(" offset: 0x%lx", offset); + PRINTLNF(" size: %lu", size); + PRINTLNF(" link: %lu", link); + PRINTLNF(" info: %lu", info); + PRINTLNF(" addralign: %lu", addralign); + PRINTLNF(" entsize: %lu", s_entsize); + PRINTLN (" }"); + + section = + (const struct KernAux_ELF_Section*) + (((const uint8_t*)section) + tag->entsize); + } + + PRINTLN(" ]"); + } FOOTER; } @@ -610,3 +717,45 @@ void KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr_print( FOOTER; } + +void KernAux_ELF_Section_Flags_print( + const uint16_t flags, + const KernAux_Display display, + const unsigned basic_indentation, + const unsigned indentation_delta, + const bool indent_first +) { + KERNAUX_CAST_CONST(unsigned long, flags_ul, flags); + + if (indent_first) INDENT; + PRINTF("0x%lx (", flags_ul); + + bool is_first = true; + + for ( + size_t index = 0; + index < sizeof(section_flag_names) / sizeof(section_flag_names[0]); + ++index + ) { + if (flags & section_flag_names[index].number) { + if (is_first) { + PRINTLN(""); + } else { + PRINTLN(" |"); + } + + INDENT; + INDENT_MORE; + PRINTF("%s", section_flag_names[index].name); + is_first = false; + } + } + + if (is_first) { + PRINTLN(")"); + } else { + PRINTLN(""); + INDENT; + PRINTLN(")"); + } +} diff --git a/tests/test_elf.c b/tests/test_elf.c index 29f77fab..d71c24a2 100644 --- a/tests/test_elf.c +++ b/tests/test_elf.c @@ -4,25 +4,4 @@ #include -#include -#include -#include -#include - -#define BUFFER_SIZE (1024 * 1024) - -void test_main(int argc, char **argv) -{ - assert(argc >= 1); - - FILE *const fd = fopen(argv[0], "r"); - assert(fd); - - uint8_t buffer[BUFFER_SIZE]; - const size_t size = fread(buffer, sizeof(uint8_t), BUFFER_SIZE, fd); - assert(size > 0); - - assert(KernAux_ELF_Header_is_valid((struct KernAux_ELF_Header*)buffer)); - - fclose(fd); -} +void test_main() {} From bf13320c2f03cf1020cd503188b42a35642c2bac Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Tue, 20 Dec 2022 11:12:30 +0400 Subject: [PATCH 2/2] FreeBSD port (#155) --- .cirrus.yml | 16 ++++++++++++++ pkgs/freebsd/.gitignore | 1 + pkgs/freebsd/devel/libkernaux/Makefile | 18 ++++++++++++++++ pkgs/freebsd/devel/libkernaux/distinfo | 3 +++ pkgs/freebsd/devel/libkernaux/pkg-descr | 3 +++ pkgs/freebsd/devel/libkernaux/pkg-plist | 28 +++++++++++++++++++++++++ 6 files changed, 69 insertions(+) create mode 100644 pkgs/freebsd/.gitignore create mode 100644 pkgs/freebsd/devel/libkernaux/Makefile create mode 100644 pkgs/freebsd/devel/libkernaux/distinfo create mode 100644 pkgs/freebsd/devel/libkernaux/pkg-descr create mode 100644 pkgs/freebsd/devel/libkernaux/pkg-plist diff --git a/.cirrus.yml b/.cirrus.yml index ba5f2662..62fd6488 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -86,3 +86,19 @@ rust_freebsd_task: - ~/.cargo/bin/cargo test - ~/.cargo/bin/cargo clippy - ~/.cargo/bin/cargo fmt --check + +main_freebsd_port_task: + name: Main (FreeBSD port) + only_if: "changesInclude('.cirrus.yml', 'pkgs/freebsd/**')" + dependencies_script: + - pkg install --yes portfmt portlint porttools + port_prepare_script: + - echo 'DEVELOPER=yes' >> /etc/make.conf + - rm -rf /usr/ports/devel/libkernaux/ + - cp -r $CIRRUS_WORKING_DIR/pkgs/freebsd/devel/libkernaux /usr/ports/devel/ + port_test_script: + - cd /usr/ports/devel/libkernaux/ + - portfmt -D Makefile + - portclippy --strict Makefile + - portlint -A + - port test . diff --git a/pkgs/freebsd/.gitignore b/pkgs/freebsd/.gitignore new file mode 100644 index 00000000..caefc693 --- /dev/null +++ b/pkgs/freebsd/.gitignore @@ -0,0 +1 @@ +/devel/libkernaux/work/ diff --git a/pkgs/freebsd/devel/libkernaux/Makefile b/pkgs/freebsd/devel/libkernaux/Makefile new file mode 100644 index 00000000..b3c122a5 --- /dev/null +++ b/pkgs/freebsd/devel/libkernaux/Makefile @@ -0,0 +1,18 @@ +PORTNAME= libkernaux +DISTVERSION= 0.6.1 +CATEGORIES= devel +MASTER_SITES= https://github.com/tailix/libkernaux/releases/download/v${DISTVERSION}/ + +MAINTAINER= kotovalexarian@gmail.com +COMMENT= Auxiliary library for kernel development +WWW= https://github.com/tailix/libkernaux + +LICENSE= MIT +LICENSE_FILE= ${WRKSRC}/COPYING + +USES= libtool +USE_LDCONFIG= yes +GNU_CONFIGURE= yes +CONFIGURE_ARGS+= --enable-shared + +.include diff --git a/pkgs/freebsd/devel/libkernaux/distinfo b/pkgs/freebsd/devel/libkernaux/distinfo new file mode 100644 index 00000000..9afb268d --- /dev/null +++ b/pkgs/freebsd/devel/libkernaux/distinfo @@ -0,0 +1,3 @@ +TIMESTAMP = 1671469243 +SHA256 (libkernaux-0.6.1.tar.gz) = 16fc83a36826cad527ec0a232032b7b131b5be0468ccff9163df12e3e3986b9f +SIZE (libkernaux-0.6.1.tar.gz) = 486595 diff --git a/pkgs/freebsd/devel/libkernaux/pkg-descr b/pkgs/freebsd/devel/libkernaux/pkg-descr new file mode 100644 index 00000000..01173d62 --- /dev/null +++ b/pkgs/freebsd/devel/libkernaux/pkg-descr @@ -0,0 +1,3 @@ +Auxiliary library for kernel development. + +It's in the early stage of the development so there is no detailed description. diff --git a/pkgs/freebsd/devel/libkernaux/pkg-plist b/pkgs/freebsd/devel/libkernaux/pkg-plist new file mode 100644 index 00000000..9be2c859 --- /dev/null +++ b/pkgs/freebsd/devel/libkernaux/pkg-plist @@ -0,0 +1,28 @@ +include/kernaux.h +include/kernaux/arch/i386.h +include/kernaux/arch/riscv64.h +include/kernaux/arch/x86.h +include/kernaux/arch/x86_64.h +include/kernaux/assert.h +include/kernaux/cmdline.h +include/kernaux/elf.h +include/kernaux/free_list.h +include/kernaux/generic/malloc.h +include/kernaux/generic/mutex.h +include/kernaux/macro.h +include/kernaux/macro/packing_end.run +include/kernaux/macro/packing_start.run +include/kernaux/mbr.h +include/kernaux/memmap.h +include/kernaux/multiboot2.h +include/kernaux/multiboot2/header_macro.h +include/kernaux/ntoa.h +include/kernaux/pfa.h +include/kernaux/printf.h +include/kernaux/printf_fmt.h +include/kernaux/units.h +include/kernaux/version.h +lib/libkernaux.a +lib/libkernaux.so +lib/libkernaux.so.0 +lib/libkernaux.so.0.0.0