From a8b2282eb88f24c3c5f461e1557fa2cf76ebc251 Mon Sep 17 00:00:00 2001 From: turret Date: Sun, 19 Nov 2023 18:57:55 -0600 Subject: Initial commit - create subsystem system using clone syscall, shared memory, shared file descriptors - printk-like logging facility (TODO: console loglevel) - initcall system (like linux kernel) TODO: determine license factors: linker.ld, linux kernel licensing (some ideas are more liberally taken rather than paraphrased) --- .gitignore | 2 + Makefile | 21 +++++ include/config.h | 4 + include/init.h | 23 +++++ include/log.h | 42 ++++++++++ include/subsys.h | 7 ++ include/util.h | 5 ++ init/init.c | 60 +++++++++++++ init/log.c | 69 +++++++++++++++ init/subsys.c | 55 ++++++++++++ init/util.c | 22 +++++ linker.ld | 251 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ net/net.c | 2 + 13 files changed, 563 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 include/config.h create mode 100644 include/init.h create mode 100644 include/log.h create mode 100644 include/subsys.h create mode 100644 include/util.h create mode 100644 init/init.c create mode 100644 init/log.c create mode 100644 init/subsys.c create mode 100644 init/util.c create mode 100644 linker.ld create mode 100644 net/net.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..16ba087 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.o +app diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8a8503e --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +CC = gcc +CFLAGS = -std=c99 -O3 -g -Wall -Wextra -Wpedantic -masm=intel +CFLAGS += -Iinclude -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L +CFLAGS += -Wno-unused-result +LDFLAGS = -Tlinker.ld -no-pie + +SRC = $(wildcard *.c **/*.c) +OBJ = $(SRC:.c=.o) + +.PHONY: all clean + +all: app + +%.o: %.c + $(CC) -o $@ -c $< $(CFLAGS) + +app: $(OBJ) + $(CC) -o app $^ $(LDFLAGS) + +clean: + rm -rf $(OBJ) app diff --git a/include/config.h b/include/config.h new file mode 100644 index 0000000..4254edc --- /dev/null +++ b/include/config.h @@ -0,0 +1,4 @@ +#define VERSION "0.0.1" +#define NAME_SHORTHAND "TCDBF" +#define NAME "turret.'s C Discord Bot Framework" + diff --git a/include/init.h b/include/init.h new file mode 100644 index 0000000..c9d8cba --- /dev/null +++ b/include/init.h @@ -0,0 +1,23 @@ +#ifndef __INIT_H +#define __INIT_H + +typedef int (*initcall_t)(void); +typedef initcall_t initcall_entry_t; + +#define __define_initcall(fn, id) \ + static initcall_t __initcall_##fn##id \ + __attribute__((used)) \ + __attribute__((section(".initcall" #id ".init"))) = fn + +#define l1_initcall(fn) __define_initcall(fn, 1) +#define l2_initcall(fn) __define_initcall(fn, 2) +#define l3_initcall(fn) __define_initcall(fn, 3) +#define l4_initcall(fn) __define_initcall(fn, 4) +#define l5_initcall(fn) __define_initcall(fn, 5) + +static inline initcall_t initcall_from_entry(initcall_entry_t *entry) +{ + return *entry; +} + +#endif diff --git a/include/log.h b/include/log.h new file mode 100644 index 0000000..52d45ff --- /dev/null +++ b/include/log.h @@ -0,0 +1,42 @@ + +#define LOG_SOH "\001" +#define LOG_SOH_ASCII '\001' + +#define LOG_EMERG LOG_SOH "0" +#define LOG_ALERT LOG_SOH "1" +#define LOG_CRIT LOG_SOH "2" +#define LOG_ERR LOG_SOH "3" +#define LOG_WARNING LOG_SOH "4" +#define LOG_NOTICE LOG_SOH "5" +#define LOG_INFO LOG_SOH "6" +#define LOG_DEBUG LOG_SOH "7" + +#define LOG_DEFAULT "" + +int print(const char *fmt, ...); + +#define ANSI_CSI "\x1b[" + +#define ANSI_BOLD ANSI_CSI "1m" +#define ANSI_ITALIC ANSI_CSI "3m" +#define ANSI_BLINK ANSI_CSI "5m" +#define ANSI_REVERSE ANSI_CSI "7m" +#define ANSI_RESET ANSI_CSI "0m" + +#define ANSI_BLACK ANSI_CSI "30m" +#define ANSI_RED ANSI_CSI "31m" +#define ANSI_GREEN ANSI_CSI "32m" +#define ANSI_YELLOW ANSI_CSI "33m" +#define ANSI_BLUE ANSI_CSI "34m" +#define ANSI_MAGENTA ANSI_CSI "35m" +#define ANSI_CYAN ANSI_CSI "36m" +#define ANSI_WHITE ANSI_CSI "37m" + +#define ANSI_BRIGHT_BLACK ANSI_CSI "90m" +#define ANSI_BRIGHT_RED ANSI_CSI "91m" +#define ANSI_BRIGHT_GREEN ANSI_CSI "92m" +#define ANSI_BRIGHT_YELLOW ANSI_CSI "93m" +#define ANSI_BRIGHT_BLUE ANSI_CSI "94m" +#define ANSI_BRIGHT_MAGENTA ANSI_CSI "95m" +#define ANSI_BRIGHT_CYAN ANSI_CSI "96m" +#define ANSI_BRIGHT_WHITE ANSI_CSI "97m" diff --git a/include/subsys.h b/include/subsys.h new file mode 100644 index 0000000..1515293 --- /dev/null +++ b/include/subsys.h @@ -0,0 +1,7 @@ +#ifndef __SUBSYS_H +#define __SUBSYS_H + +int __impl_start_subsystem(char *name, int (*fn)(void)); +#define start_subsystem(fn) __impl_start_subsystem(#fn, fn) + +#endif diff --git a/include/util.h b/include/util.h new file mode 100644 index 0000000..97435be --- /dev/null +++ b/include/util.h @@ -0,0 +1,5 @@ +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +void die(const char *fmt, ...); + +#define writeputs(str) write(STDOUT_FILENO, str, strlen(str)); diff --git a/init/init.c b/init/init.c new file mode 100644 index 0000000..5363082 --- /dev/null +++ b/init/init.c @@ -0,0 +1,60 @@ +#include +#include + +#include +#include + +/* For some reason, I get SIGSEGV'd when running because a random-ass + byte was inserted where it isnt supposed to be. Added a safety byte + because I cannot be asked to try to figure out how to do this cleanly. */ +static unsigned long __1bsafebuf + __attribute__((used)) __attribute__((section(".1bsafebuf.init"))) = 0; + +extern initcall_entry_t __initcall1_start[]; +extern initcall_entry_t __initcall2_start[]; +extern initcall_entry_t __initcall3_start[]; +extern initcall_entry_t __initcall4_start[]; +extern initcall_entry_t __initcall5_start[]; +extern initcall_entry_t __initcall_end[]; + +static initcall_entry_t *initcall_levels[] = { + __initcall1_start, + __initcall2_start, + __initcall3_start, + __initcall4_start, + __initcall5_start, + __initcall_end, +}; + +static void do_initcall_level(int level) +{ + initcall_entry_t *fn; + + for (fn = initcall_levels[level - 1]; fn < initcall_levels[level]; fn++) + initcall_from_entry(fn)(); +} + +static void do_initcalls(void) +{ + unsigned long level; + for (level = 1; level < ARRAY_SIZE(initcall_levels); level++) { + do_initcall_level(level); + } +} + +int main(void) +{ + do_initcalls(); + + static sigset_t set; + sigaddset(&set, SIGCHLD); + sigprocmask(SIG_BLOCK, &set, NULL); + + while(1) { + int sig; + sigwait(&set, &sig); + if(sig == SIGCHLD) + while(waitpid(0, NULL, WNOHANG) > 0) + ; + } +} diff --git a/init/log.c b/init/log.c new file mode 100644 index 0000000..3cdaa06 --- /dev/null +++ b/init/log.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include + +#include +#include + +static const char *colors[] = { + [0] = ANSI_BLINK ANSI_REVERSE ANSI_BOLD ANSI_RED, + [1] = ANSI_REVERSE ANSI_BOLD ANSI_RED, + [2] = ANSI_BOLD ANSI_RED, + [3] = ANSI_RED, + [4] = ANSI_BOLD, + [5] = ANSI_BRIGHT_WHITE, + [6] = ANSI_RESET, + [7] = ANSI_ITALIC ANSI_BRIGHT_BLUE, +}; + +int console_lock = 0; + +int print(const char *fmt, ...) +{ + int loglevel = 5; + if(fmt[0] == LOG_SOH_ASCII) { + loglevel = (fmt[1] - 0x30) % 10; + fmt += 2; + } + + char buf[512]; + + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, 512, fmt, ap); + va_end(ap); + buf[512 - 1] = '\0'; + + size_t colon = 0; + for(; colon < strlen(buf); ++colon) { + if(buf[colon] == ':') + break; + } + + /* spin lock, at the cost of architecture portability */ + __asm__(".spin_lock:"); + __asm__("mov rax, 1"); + __asm__("xchg rax, [console_lock]"); + __asm__("test rax, rax"); + __asm__("jnz .spin_lock"); + + if(buf[colon] == ':') { + writeputs(ANSI_RESET); + writeputs(colors[loglevel]); + writeputs(ANSI_YELLOW); + write(STDOUT_FILENO, buf, colon); + writeputs(ANSI_RESET); + } + writeputs(colors[loglevel]); + if(colon && *(buf + colon)) { + writeputs(buf + colon); + } else { + writeputs(buf); + } + writeputs(ANSI_RESET); + + console_lock = 0; + return 0; +} diff --git a/init/subsys.c b/init/subsys.c new file mode 100644 index 0000000..0435f1a --- /dev/null +++ b/init/subsys.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define STACK_SIZE 8192 * 512 + +struct subsystem_info { + char *fn_name; + int (*fn)(void); +}; + +int __subsystem_entry(struct subsystem_info *info) +{ + + char *name = malloc(16 * sizeof(char)); + snprintf(name, 16, NAME_SHORTHAND ": %s", info->fn_name); + name[15] = '\0'; + prctl(PR_SET_NAME, name); + free(name); + + int ret = info->fn(); + + free(info); + + return ret; +} + +int __impl_start_subsystem(char *fn_name, int (*fn)(void)) +{ + void *stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_GROWSDOWN | MAP_STACK | MAP_PRIVATE, -1, 0); + if((long)stack < 0) + die("subsys mmap:"); + + struct subsystem_info *info = malloc(sizeof(struct subsystem_info)); + info->fn_name = fn_name; + info->fn = fn; + + int pid = clone((int (*)(void *))__subsystem_entry, stack, CLONE_FILES | CLONE_VM, info); + if(pid < 0) { + munmap(stack, STACK_SIZE); + die("subsys clone:"); + } + + return 0; +} diff --git a/init/util.c b/init/util.c new file mode 100644 index 0000000..1a08234 --- /dev/null +++ b/init/util.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +void die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + if(fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } + + exit(1); +} diff --git a/linker.ld b/linker.ld new file mode 100644 index 0000000..71e8b89 --- /dev/null +++ b/linker.ld @@ -0,0 +1,251 @@ +/* Default linker script, for normal executables */ +/* Copyright (C) 2014-2023 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", + "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(_start) +SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64"); SEARCH_DIR("/usr/lib64/binutils/x86_64-pc-linux-gnu/2.4064"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib"); SEARCH_DIR("/usr/lib64/binutils/x86_64-pc-linux-gnu/2.40"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.init : { *(.rela.init) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rela.fini : { *(.rela.fini) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rela.data.rel.ro : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } + .rela.ctors : { *(.rela.ctors) } + .rela.dtors : { *(.rela.dtors) } + .rela.got : { *(.rela.got) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rela.ldata : { *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*) } + .rela.lbss : { *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*) } + .rela.lrodata : { *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*) } + .rela.ifunc : { *(.rela.ifunc) } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .relr.dyn : { *(.relr.dyn) } + .init : + { + KEEP (*(SORT_NONE(.init))) + } + .plt : { *(.plt) *(.iplt) } +.plt.got : { *(.plt.got) } +.plt.sec : { *(.plt.sec) } + .text : + { + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(SORT(.text.sorted.*)) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf.em. */ + *(.gnu.warning) + + . = ALIGN(8); + KEEP(*(.1bsafebuf.init)) + __initcall1_start = .; KEEP(*(.initcall1.init)) + __initcall2_start = .; KEEP(*(.initcall2.init)) + __initcall3_start = .; KEEP(*(.initcall3.init)) + __initcall4_start = .; KEEP(*(.initcall4.init)) + __initcall5_start = .; KEEP(*(.initcall5.init)) + __initcall_end = .; + } + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .sframe : ONLY_IF_RO { *(.sframe) *(.sframe.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .sframe : ONLY_IF_RW { *(.sframe) *(.sframe.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : + { + PROVIDE_HIDDEN (__tdata_start = .); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .); + .got.plt : { *(.got.plt) *(.igot.plt) } + .data : + { + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _edata = .; PROVIDE (edata = .); + . = .; + __bss_start = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we do not + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + .lbss : + { + *(.dynlbss) + *(.lbss .lbss.* .gnu.linkonce.lb.*) + *(LARGE_COMMON) + } + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : + { + *(.lrodata .lrodata.* .gnu.linkonce.lr.*) + } + .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : + { + *(.ldata .ldata.* .gnu.linkonce.l.*) + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + . = ALIGN(64 / 8); + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1. */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions. */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2. */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2. */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions. */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3. */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF 5. */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} diff --git a/net/net.c b/net/net.c new file mode 100644 index 0000000..11c66ff --- /dev/null +++ b/net/net.c @@ -0,0 +1,2 @@ +#include + -- cgit v1.2.3