Update librairies part + auto-load TTY device when STD[OUT/ERR/IN]_FILENO is specified + Try to create dynamic libs (not work)

This commit is contained in:
Yann MAGNIN 2020-03-20 22:47:05 +01:00
parent 67201cd226
commit f02487d856
41 changed files with 367 additions and 142 deletions

View File

@ -1,7 +1,7 @@
# Global option use in each Makefile
# Tools
COMPILER := sh3eb-elf-
COMPILER := sh-elf-
CC := $(COMPILER)gcc
LD := $(COMPILER)ld
OBJCOPY := $(COMPILER)objcopy

View File

@ -18,19 +18,29 @@
//TODO: signal !
struct process
{
//---
// Used when interrupt or exception occur
//---
struct {
uint32_t kernel;
uint32_t user;
} stack;
//---
// Context management
//---
common_context_t context;
// Process name.
//---
// Private data
//---
char name[PROCESS_NAME_LENGHT];
// Open file management
//---
// Shared (child / parent) data informations
//---
struct {
enum {
PROCESS_FILE_SLOT_UNUSED,
@ -39,16 +49,22 @@ struct process
FILE file;
} opfile[PROCESS_NB_OPEN_FILE];
struct dentry *working_dir;
FILE tty;
// ignals management.
//---
// Signals management.
//---
//sighandler_t signal[NSIG];
//---
// Virtual / Physical memory management.
//
// @note
// For now, we can not use the MMU
// so we just save all physical allocated
// space. This is an hardcode of each
// process memory management.
// For now, we can not use the MMU so we just
// save all physical allocated space. This is an
// hardcode of each process memory management.
//---
struct {
struct {
uint32_t user;
@ -67,13 +83,17 @@ struct process
uint32_t size;
} exit;
} memory;
//---
// Other process management.
//---
struct process *parent;
struct process *child;
struct process *next;
};
// Internal struct used by the
// static process stack
struct process_stack
@ -88,12 +108,14 @@ struct process_stack
struct process process;
};
// Functions.
extern struct process *process_create(const char *name);
extern struct process *process_get(pid_t pid);
extern pid_t process_get_pid(struct process *process);
extern int process_switch(pid_t pid);
// Internal function.
extern pid_t process_alloc(struct process **process);
extern int process_free(struct process *process);

View File

@ -6,7 +6,16 @@
#include <stdarg.h>
/* vsprintf(), sprintf() - formatted output conversion. */
int vsprintf(char *str, char const *format, va_list ap);
void sprintf(char *str, char const *format, ...);
extern int vsprintf(char *str, char const *format, va_list ap);
extern int sprintf(char *str, char const *format, ...);
/* dprintf(), printf() - display formatted output */
extern int printf(const char *format, ...);
extern int dprintf(int fd, const char *format, ...);
extern int vdprintf(int fd, const char *format, va_list ap);
/* putx() - display char / string */
extern int putchar(int c);
extern int puts(const char *s);
#endif /*__LIB_STDIO_H__*/

View File

@ -8,6 +8,10 @@
// Define syscall LIST
#include <kernel/util/unistd_32.h>
// TODO: move me
#define STDOUT_FILENO 0
#define STDERR_FILENO 1
#define STDIN_FILENO 2
//TODO: move me
#define WNOHANG 0

View File

@ -27,8 +27,8 @@ struct builtin_s
};
// Builtin list
//extern int builtin_proc(void);
//extern int builtin_ram(void);
extern int builtin_proc(void);
extern int builtin_ram(void);
#endif /*__USER_BUILTIN_H__*/

View File

@ -5,10 +5,14 @@ int sys_close(int fd)
{
extern struct process *process_current;
// Check fd
if (fd < 0 || fd >= PROCESS_NB_OPEN_FILE)
// Check fd validity
if (fd < 0 || fd - 3 >= PROCESS_NB_OPEN_FILE)
return (-1);
// call VFS close primitive
return (vfs_close(&process_current->opfile[fd].file));
// Check virtual file (TTY)
if (fd < 3)
return (0);
// Call VFS close primitive
return (vfs_close(&process_current->opfile[fd - 3].file));
}

View File

@ -6,9 +6,13 @@ off_t sys_lseek(int fd, off_t offset, int whence)
extern struct process *process_current;
// Check fd
if (fd < 0 || fd >= PROCESS_NB_OPEN_FILE)
if (fd < 0 || fd - 3 >= PROCESS_NB_OPEN_FILE)
return (-1);
// call VFS read primitive
return (vfs_lseek(&process_current->opfile[fd].file, offset, whence));
// Check virtual file (TTY)
if (fd < 3)
return (0);
// Call VFS lseek primitive
return (vfs_lseek(&process_current->opfile[fd - 3].file, offset, whence));
}

View File

@ -24,5 +24,9 @@ int sys_open(const char *pathname, int flags, ...)
return (-1);
// Return the file descriptor
return (fd);
// @note:
// * fd = 0 -> STDOUT_FILENO
// * fd = 1 -> STDERR_FILENO
// * fd = 2 -> STDIN_FILENO
return (fd + 3);
}

View File

@ -6,9 +6,17 @@ ssize_t sys_read(int fd, void *buf, size_t count)
extern struct process *process_current;
// Check fd
if (fd < 0 || fd >= PROCESS_NB_OPEN_FILE)
if (fd < 0 || fd - 3 >= PROCESS_NB_OPEN_FILE)
return (-1);
// Check virtual file (TTY) and open it if needed
if (fd < 3) {
if (process_current->tty.private == NULL &&
vfs_open(&process_current->tty, "/dev/tty", O_RDWR) != 0)
return (-1);
return (vfs_read(&process_current->tty, buf, count));
}
// call VFS read primitive
return (vfs_read(&process_current->opfile[fd].file, buf, count));
return (vfs_read(&process_current->opfile[fd - 3].file, buf, count));
}

View File

@ -6,9 +6,17 @@ ssize_t sys_write(int fd, const void *buf, size_t count)
extern struct process *process_current;
// Check fd
if (fd < 0 || fd >= PROCESS_NB_OPEN_FILE)
if (fd < 0 || fd - 3 >= PROCESS_NB_OPEN_FILE)
return (-1);
// Check virtual file (TTY) and open it if needed
if (fd < 3) {
if (process_current->tty.private == NULL &&
vfs_open(&process_current->tty, "/dev/tty", O_RDWR) != 0)
return (-1);
return (vfs_write(&process_current->tty, buf, count));
}
// call VFS read primitive
return (vfs_write(&process_current->opfile[fd].file, buf, count));
}

View File

@ -50,7 +50,6 @@ struct process *process_create(const char *name)
process->stack.kernel = process->memory.stack.kernel + process->memory.stack.size.kernel;
// initialize "exit" part.
// FIXME: add xor r4, r4
uint8_t callexit[8] = {
0b00100100, 0b01001010, // xor r4, r4
0b11000011, __NR_exit, // trapa #__NR_exit
@ -93,12 +92,13 @@ struct process *process_create(const char *name)
process->opfile[i].file.cursor = 0;
}
process->working_dir = vfs_root_node;
process->tty.private = NULL;
// DEBUG !
earlyterm_write("proc_create: success !\n");
earlyterm_write("* user stack: %p\n", process->context.reg[15]);
earlyterm_write("* kernel stack: %p\n", process->memory.stack.kernel);
DBG_WAIT;
//earlyterm_write("proc_create: success !\n");
//earlyterm_write("* user stack: %p\n", process->context.reg[15]);
//earlyterm_write("* kernel stack: %p\n", process->memory.stack.kernel);
//DBG_WAIT;
// Link new process with his parent.
// @Note:

View File

@ -3,12 +3,26 @@
#include <kernel/loader.h>
#include <kernel/util/atomic.h>
#include <kernel/devices/earlyterm.h>
#include <lib/string.h>
static void proc_dump_shared(struct process *child, struct process *parent)
{
// Dump all opened file
for (int i = 0 ; i < PROCESS_NB_OPEN_FILE ; ++i)
{
memcpy(&child->opfile[i].file, &parent->opfile[i].file, sizeof(FILE));
child->opfile[i].status = parent->opfile[i].status;
}
// Dump specific
memcpy(&child->tty, &parent->tty, sizeof(FILE));
}
pid_t sys_fexecve(const char *pathname)
{
extern struct process *process_current;
struct process *proc;
pid_t child_pid;
int error;
// Start atomic operation
atomic_start();
@ -17,12 +31,16 @@ pid_t sys_fexecve(const char *pathname)
proc = process_create(pathname);
if (proc == NULL)
{
earlyterm_write("sys_fexecve: alloc error !");
earlyterm_write("sys_fexecve: process_create error !\n");
DBG_WAIT;
atomic_stop();
return (-1);
}
// Dump parent process shared informations
if (process_current != NULL)
proc_dump_shared(proc, process_current);
// Try to load binary into physical memory
if (loader(proc, pathname) != 0)
{
@ -33,13 +51,8 @@ pid_t sys_fexecve(const char *pathname)
return (-1);
}
// Debug
earlyterm_write("New proc loaded !");
DBG_WAIT;
// Add new process into task queue
error = sched_add_task(proc);
if (error != 0)
if (sched_add_task(proc))
{
earlyterm_write("sys_fexecve: scheduler error !");
DBG_WAIT;

View File

@ -12,8 +12,10 @@ include ../../global.mk
# Generic variables #
#------- --------#
HEADER := -I../../include
BUILD := ../../build/lib/
TARGET-MODULES := stdio string unistd display
BUILD-STATIC := ../../build/lib/static
BUILD-DYNAMIC := ../../build/lib/dynamic
TARGET-MODULES := libc display
DEBUG-DYNLIB := ../../debug_bin
@ -21,14 +23,20 @@ TARGET-MODULES := stdio string unistd display
#------- --------#
# Automated variables #
#------- --------#
$(foreach mod,$(TARGET-MODULES),$(eval \
target-$(mod)-src := $$(wildcard $(mod)/*.c) $n\
target-$(mod)-src += $$(wildcard $(mod)/*.s) $n\
target-$(mod)-src += $$(wildcard $(mod)/*.S) $n\
target-$(mod)-obj := $$(subst /,_,$$(basename $$(target-$(mod)-src))) $n\
target-$(mod)-obj := $$(patsubst %,$(BUILD)%.o,$$(target-$(mod)-obj)) $n\
$(foreach mod,$(TARGET-MODULES),$(eval \
target-$(mod)-dir := $(shell find $(mod) -type d) $n\
target-$(mod)-src := $n\
$$(foreach path,$$(target-$(mod)-dir),$$(eval $$n\
target-$(mod)-src += $$$$(wildcard $$(path)/*.c) $$n\
target-$(mod)-src += $$$$(wildcard $$(path)/*.s) $$n\
target-$(mod)-src += $$$$(wildcard $$(path)/*.S) $$n\
)) $n\
target-$(mod)-obj := $$(subst /,_,$$(basename $$(target-$(mod)-src))) $n\
target-$(mod)-obj-static := $$(patsubst %,$(BUILD-STATIC)/%.o,$$(target-$(mod)-obj)) $n\
target-$(mod)-obj-dynamic := $$(patsubst %,$(BUILD-DYNAMIC)/%.o,$$(target-$(mod)-obj)) $n\
))
TARGET-LIBS := $(patsubst %,lib%.a,$(TARGET-MODULES))
TARGET-LIBS-STATIC := $(patsubst %,lib%.a,$(TARGET-MODULES))
TARGET-LIBS-DYNAMIC := $(patsubst %,lib%_dyn.so,$(TARGET-MODULES))
@ -36,49 +44,56 @@ TARGET-LIBS := $(patsubst %,lib%.a,$(TARGET-MODULES))
#------- --------#
# Generic rules #
#------- --------#
all: $(TARGET-LIBS)
all: $(TARGET-LIBS-STATIC) $(TARGET-LIBS-DYNAMIC)
$(BUILD):
$(BUILD-STATIC) $(BUILD-DYNAMIC):
@ printf "Create $(blue)$@$(nocolor) directory\n"
@ mkdir -p $@
debug:
@ echo 'lib: $(TARGET-LIBS)'
@ echo 'src: $(target-stdio-src)'
@ echo 'obj: $(target-stdio-obj)'
@ echo 'directory: $(TARGET-MODULES)'
@ echo 'debug: $(BUILD)'
#------- --------#
# Rule functions #
#------- --------#
define rule-src
$(patsubst %,$(BUILD)%.o,$(subst /,_,$(basename $1))): $1 | $(BUILD)
define rule-src-static
$(patsubst %,$(BUILD-STATIC)/%.o,$(subst /,_,$(basename $1))): $1 | $(BUILD-STATIC)
@ printf "compiling $(white)$$<$(nocolor)..."
@ $(CC) $(CFLAGS) -c $$< -o $$@ $(HEADER)
@ printf "$(green)[ok]$(nocolor)\n"
endef
define rule-link
define rule-link-static
$(patsubst %,lib%.a,$1): $2
@ printf "Link $(green)$$@$(nocolor) lib\n"
$(AR) crs $$@ $$^
endef
define rule-src-dynamic
$(patsubst %,$(BUILD-DYNAMIC)/%.o,$(subst /,_,$(basename $1))): $1 | $(BUILD-DYNAMIC)
@ printf "compiling $(white)$$<$(nocolor)..."
@ $(CC) -fPIC $(CFLAGS) -c $$< -o $$@ $(HEADER)
@ printf "$(green)[ok]$(nocolor)\n"
endef
define rule-link-dynamic
$(patsubst %,lib%_dyn.so,$1): $2 | $(DEBUG-DYNLIB)
@ printf "Link $(green)$$@$(nocolor) lib\n"
$(CC) -shared -o $$@ $$^ -nostdlib -lgcc
endef
#------- --------#
# Automated rules #
#------- --------#
$(foreach mod,$(TARGET-MODULES), \
$(foreach source,$(target-$(mod)-src), \
$(eval $(call rule-src,$(source),$(mod)))) \
$(eval $(call rule-link,$(mod),$(target-$(mod)-obj))) \
$(foreach mod,$(TARGET-MODULES), \
$(foreach source,$(target-$(mod)-src), \
$(eval $(call rule-src-static,$(source)))) \
$(eval $(call rule-link-static,$(mod),$(target-$(mod)-obj-static))) \
)
$(foreach mod,$(TARGET-MODULES), \
$(foreach source,$(target-$(mod)-src), \
$(eval $(call rule-src-dynamic,$(source)))) \
$(eval $(call rule-link-dynamic,$(mod),$(target-$(mod)-obj-dynamic))) \
)
@ -86,10 +101,12 @@ $(foreach mod,$(TARGET-MODULES), \
# Clean rules #
#------- --------#
clean:
rm -rf $(BUILD)
rm -rf $(BUILD-STATIC)
rm -rf $(BUILD-DYNAMIC)
fclean: clean
rm -f $(TARGET-LIBS)
rm -f $(TARGET-LIBS-STATIC)
rm -f $(TARGET-LIBS-DYNAMIC)
re: fclean all

View File

@ -0,0 +1,13 @@
#include <lib/stdio.h>
#include <lib/unistd.h>
int printf(const char *format, ...)
{
va_list ap;
int ret;
va_start(ap, format);
ret = vdprintf(STDOUT_FILENO, format, ap);
va_end(ap);
return (ret);
}

11
src/lib/libc/stdio/putc.c Normal file
View File

@ -0,0 +1,11 @@
#include <lib/stdio.h>
#include <lib/unistd.h>
int putc(int c)
{
char n;
n = (char)c;
write(STDOUT_FILENO, &n, 1);
return (n);
}

13
src/lib/libc/stdio/puts.c Normal file
View File

@ -0,0 +1,13 @@
#include <lib/stdio.h>
#include <lib/string.h>
#include <lib/unistd.h>
int puts(const char *s)
{
size_t size;
size_t n;
size = strlen(s);
n = write(STDOUT_FILENO, s, size);
return (-(n == size));
}

View File

@ -0,0 +1,12 @@
#include <lib/stdio.h>
int sprintf(char *str, char const *format, ...)
{
va_list ap;
int ret;
va_start(ap, format);
ret = vsprintf(str, format, ap);
va_end(ap);
return (ret);
}

View File

@ -0,0 +1,8 @@
#include <lib/stdio.h>
#include <lib/unistd.h>
//TODO x_x
int vdprintf(int fd, const char *format, va_list ap)
{
return (-1);
}

View File

@ -44,6 +44,7 @@ static size_t strndump(char *dest, char const *src, size_t size)
return (i);
}
//TODO: update me !!
int vsprintf(char *str, char const *format, va_list ap)
{
const char *tmp;

View File

@ -1,10 +0,0 @@
#include <lib/stdio.h>
void sprintf(char *str, char const *format, ...)
{
va_list ap;
va_start(ap, format);
vsprintf(str, format, ap);
va_end(ap);
}

View File

@ -0,0 +1,86 @@
OUTPUT_FORMAT("elf32-sh", "elf32-sh", "elf32-sh")
OUTPUT_ARCH(sh3)
/*
** Linker script for user executables.
*/
MEMORY
{
/* virtual memory, read-write segment */
userram (WX) : o = 0x00000000, l = 256k
}
SECTIONS
{
/* Code */
.text : {
*(.text);
*(.text.*);
} > userram
/* Read-only sections */
.rodata : {
/* Read-Only data */
*(.rodata);
*(.rodata.*);
/* Dynamic symbols */
*(.hash)
*(.dynsym)
*(.dynstr)
*(.dynbss)
*(.dynamic)
/* Procedure Linkage Table */
*(.plt)
/* GLobal Offset Table */
*(.got.plt)
*(.got.*)
*(.got)
/* ???? */
*(.rofixup)
} > userram
/* Relocatable sections */
.rela.dyn : {
*(.rela.plt)
*(.rela.got)
*(.rela.got.*)
*(.rela.*)
*(.rela.text)
*(.real.data)
} > userram
/* readable / writable data */
.data ALIGN(4) : {
/* Data sections */
*(.data);
*(.data.*);
/* bss section included to avoid missaligned segment */
*(.bss);
*(.bss.*);
*(COMMON);
} > userram
/* unwanted section */
/DISCARD/ : {
*(.gnu.*)
*(.debug_info)
*(.debug_abbrev)
*(.debug_loc)
*(.debug_aranges)
*(.debug_ranges)
*(.debug_line)
*(.debug_str)
*(.jcr)
*(.eh_frame_hdr)
*(.eh_frame)
*(.comment)
*(.interp)
}
}

View File

@ -1,43 +1,24 @@
#include <lib/unistd.h>
#include <lib/display.h>
#include <lib/stdio.h>
#include <builtin.h>
int builtin_proc(void)
{
// pid_t child;
pid_t child;
int wstatus;
// Debug
// dclear();
// dprint(0, 0, "Proc builtin !");
// dupdate();
for (int i = 0 ; i < 3000000 ; i++);
puts("proc test entry :)\n");
// Try to create first child
/*child = fork();
child = fexecve("/mnt/casio/VHEX/test.elf");
if (child == -1)
{
dprint(0, 1, "fork() fail !");
dupdate();
for (int i = 0 ; i < 3000000 ; i++);
puts("fexecve fail :(\n");
return (0);
}
// Check parent
if (child_pid != 0)
{
int counter = 0;
while (1)
{
dprint(0, 1, "parent: %d", counter++);
for (int i = 0 ; i < 3000000 ; i++);
}
} else {
int counter = 0;
while (1)
{
dprint(0, 2, "child: %d", counter++);
for (int i = 0 ; i < 9000000 ; i++);
}
}*/
// Wait child death
waitpid(child, &wstatus, WUNTRACED);
return (0);
}

View File

@ -9,15 +9,15 @@ int main(void)
int cmd_size;
//char **argv;
//int argc;
int fd;
//int STDOUT_FILENO;
// Try to open TTY
// @note:
// We use O_DIRECT to avoid cache
// generation because we do not have a
// lot of memory.
fd = open("/dev/tty", O_DIRECT);
if (fd < 0)
/*STDOUT_FILENO = open("/dev/tty", O_DIRECT);
if (STDOUT_FILENO < 0)
{
// Display error.
display_t disp;
@ -35,15 +35,15 @@ int main(void)
// TODO: use sleep syscall !
__asm__ volatile ("sleep");
}
}
}*/
// Shell main loop.
write(fd, "Boot Complete !\n", 16);
write(STDOUT_FILENO, "Boot Complete !\n", 16);
while (1)
{
// Get user command.
write(fd, ">", 1);
cmd_size = read(fd, input, 12);
write(STDOUT_FILENO, ">", 1);
cmd_size = read(STDIN_FILENO, input, 12);
// Remove '\n' char.
// FIXME: create argc, argv !!
@ -52,11 +52,11 @@ int main(void)
// Check buit-in.
if (check_builtin(input) != 0)
{
write(fd, input, cmd_size - 1);
write(fd, ": command not found\n", 20);
write(STDOUT_FILENO, input, cmd_size - 1);
write(STDOUT_FILENO, ": command not found\n", 20);
} else {
write(fd, input, cmd_size - 1);
write(fd, ": command found :D !\n", 21);
write(STDOUT_FILENO, input, cmd_size - 1);
write(STDOUT_FILENO, ": command found :D !\n", 21);
}
}
return (0);

View File

@ -10,7 +10,7 @@
struct builtin_s builtin[2] = {
{
.name = "proc",
.entry = NULL
.entry = (void*)&builtin_proc
},
{
.name = "ram",

View File

@ -42,12 +42,10 @@ OBJ := $(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $(SRC)))
##---
## General rules
##---
all: | $(BUILD) $(DEBUG) $(EXEC)
all: $(EXEC)
$(EXEC): $(OBJ)
$(CC) -fPIC -Wl,-M $(LDFLAG) $(CFLAGS) -o $(DEBUG)/$(NAME).elf.big $(OBJ) $(HEADER) $(LIBS) > $(MEMORY_MAP)
$(OBJCOPY) -S $(DEBUG)/$(NAME).elf.big $@
rm -f $(DEBUG)/$(NAME).elf.big
$(EXEC): $(OBJ) | $(DEBUG)
$(CC) -pie -Wl,-M $(LDFLAG) $(CFLAGS) -o $@ $(OBJ) $(HEADER) $(LIBS) > $(MEMORY_MAP)
$(BUILD) $(DEBUG):
@ printf "Create $(blue)$@$(nocolor) directory\n"
@ -75,9 +73,9 @@ sec:
## Automated rules
##---
define rule-src
$(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $1)))): $1
$(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $1)))): $1 | $(BUILD)
@ printf "compiling $(white)$$<$(nocolor)..."
@ $(CC) -fPIC $(CFLAGS) -o $$@ -c $$< $(HEADER) -lgcc
@ $(CC) -pie $(CFLAGS) -o $$@ -c $$< $(HEADER) -lgcc
@ printf "$(green)[ok]$(nocolor)\n"
endef

View File

@ -1,5 +1,5 @@
OUTPUT_FORMAT("elf32-sh", "elf32-sh", "elf32-sh")
OUTPUT_ARCH(sh3)
OUTPUT_FORMAT(elf32-sh)
ENTRY(_main)
/*
@ -11,26 +11,51 @@ MEMORY
userram (WX) : o = 0x00000000, l = 256k
}
PHDRS
{
text PT_LOAD ;
data PT_LOAD ;
}
SECTIONS
{
/* Read-only sections */
.text : {
/* Code */
*(.text);
*(.text.*);
} : text
.rodata : {
/* Read-Only data */
*(.rodata);
*(.rodata.*);
}
/* Dynamic symbols */
*(.hash)
*(.dynsym)
*(.dynstr)
*(.dynbss)
*(.dynamic)
/* Procedure Linkage Table */
*(.plt)
/* GLobal Offset Table */
*(.got.plt)
*(.got.*)
*(.got)
/* ???? */
*(.rofixup)
} > userram
/* Relocatable sections */
.rela.dyn : {
*(.rela.plt)
*(.rela.got)
*(.rela.got.*)
*(.rela.*)
*(.rela.text)
*(.real.data)
} > userram
/* readable / writable data */
.data ALIGN(4) : {
*(.plt);
/* Data sections */
*(.data);
*(.data.*);
@ -38,18 +63,11 @@ SECTIONS
*(.bss);
*(.bss.*);
*(COMMON);
} : data
.relocgot : {
BRELOC_GOT = . ;
*(.got.plt)
*(.got)
ERELOC_GOT = . ;
}
} > userram
/* unwanted section */
/DISCARD/ : {
*(.gnu.*)
*(.debug_info)
*(.debug_abbrev)
*(.debug_loc)
@ -61,5 +79,6 @@ SECTIONS
*(.eh_frame_hdr)
*(.eh_frame)
*(.comment)
*(.interp)
}
}