simple tricks to reduce memory/binary size
This commit is contained in:
parent
d94875c788
commit
3028f3ee33
13 changed files with 99 additions and 109 deletions
6
Makefile
6
Makefile
|
|
@ -1,12 +1,14 @@
|
|||
SOURCES := src/main.c src/util/calloc.c src/util/string.c src/util/hash.c src/lexer/lexer.c src/builtins/builtins.c src/util/memset.c
|
||||
CFLAGS := -g -Oz -nostdlib
|
||||
LDFLAGS :=
|
||||
|
||||
UNAME := $(shell uname)
|
||||
ARCH := $(shell uname -m)
|
||||
|
||||
ifeq ($(UNAME), Linux)
|
||||
SOURCES += src/system/linux/linux.c src/system/linux/alloc.c src/system/linux/env.c src/system/linux/errno.c src/system/linux/signal.c
|
||||
CFLAGS += -fno-stack-protector -Wno-incompatible-library-redeclaration
|
||||
CFLAGS += -fno-stack-protector -Wno-incompatible-library-redeclaration -flto -ffunction-sections -fdata-sections -fshort-enums
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
CFLAGS += -DMSH_ENTRY_POINT="void _start()"
|
||||
ifeq ($(ARCH),i386)
|
||||
SOURCES += src/system/linux/i386.s
|
||||
|
|
@ -19,7 +21,7 @@ endif
|
|||
endif
|
||||
|
||||
all: $(SOURCES)
|
||||
$(CC) $(SOURCES) $(CFLAGS) -o msh
|
||||
$(CC) $(LDFLAGS) $(SOURCES) $(CFLAGS) -o msh
|
||||
|
||||
clean:
|
||||
rm -f *.o msh
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include "../system/system.h"
|
||||
#include "../util/util.h"
|
||||
|
||||
int hashes_calced = 0;
|
||||
char hashes_calced = 0;
|
||||
int cd_hash = 0;
|
||||
int exit_hash = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,30 +2,25 @@
|
|||
|
||||
#include "../builtins/builtins.h"
|
||||
#include "../system/system.h"
|
||||
#include <linux/limits.h>
|
||||
|
||||
struct msh_lexer_t {
|
||||
msh_lexer_item_list *item_list_head;
|
||||
msh_lexer_item_list *item_list_cur;
|
||||
char *path;
|
||||
};
|
||||
msh_lexer msh_lexer_new() {
|
||||
msh_lexer l = {0};
|
||||
l.item_list_head = msh_allocate(sizeof(struct msh_lexer_item_list_t));
|
||||
|
||||
msh_lexer *msh_lexer_new() {
|
||||
msh_lexer *l = msh_allocate(sizeof(struct msh_lexer_t));
|
||||
l->item_list_head = msh_allocate(sizeof(struct msh_lexer_item_list_t));
|
||||
l.item_list_head->item = 0;
|
||||
l.item_list_head->next = 0;
|
||||
|
||||
l->item_list_head->item = 0;
|
||||
l->item_list_head->next = 0;
|
||||
l.item_list_cur = l.item_list_head;
|
||||
|
||||
l->item_list_cur = l->item_list_head;
|
||||
|
||||
l->path = msh_env_get_path();
|
||||
l.path = msh_env_get_path();
|
||||
|
||||
return l;
|
||||
};
|
||||
|
||||
void msh_lexer_push_item(msh_lexer *lexer, msh_lexer_item_type type, char *buf,
|
||||
SIZE_TYPE strlen) {
|
||||
int i;
|
||||
unsigned short i;
|
||||
msh_lexer_item *item = msh_callocate(sizeof(msh_lexer_item), 1);
|
||||
|
||||
item->str = msh_allocate(strlen * sizeof(char));
|
||||
|
|
@ -38,14 +33,13 @@ void msh_lexer_push_item(msh_lexer *lexer, msh_lexer_item_type type, char *buf,
|
|||
lexer->item_list_cur->item = item;
|
||||
lexer->item_list_cur->next = 0;
|
||||
|
||||
lexer->item_list_cur->next = msh_callocate(sizeof(msh_lexer_item_list), 1);
|
||||
lexer->item_list_cur->next = msh_callocate(1, sizeof(msh_lexer_item_list));
|
||||
lexer->item_list_cur = lexer->item_list_cur->next;
|
||||
};
|
||||
|
||||
void msh_lexer_parse(msh_lexer *lexer, char *buf, SIZE_TYPE sz) {
|
||||
int i = 0, n = 0, j = 0;
|
||||
|
||||
char *cur_word_buf = msh_callocate(1024, sizeof(char));
|
||||
char cur_word_buf[1024];
|
||||
|
||||
/*case '#':
|
||||
do_clear = 1;
|
||||
|
|
@ -80,11 +74,11 @@ void msh_lexer_parse(msh_lexer *lexer, char *buf, SIZE_TYPE sz) {
|
|||
break;
|
||||
*/
|
||||
|
||||
int escaping = 0;
|
||||
int quote_mode = 0;
|
||||
char escaping = 0;
|
||||
char quote_mode = 0;
|
||||
|
||||
for (i = 0; i < sz; i++) {
|
||||
int do_clear = 0;
|
||||
char do_clear = 0;
|
||||
switch (buf[i]) {
|
||||
case '#':
|
||||
cur_word_buf[n++] = '\0';
|
||||
|
|
@ -125,33 +119,20 @@ void msh_lexer_parse(msh_lexer *lexer, char *buf, SIZE_TYPE sz) {
|
|||
}
|
||||
}
|
||||
lexer_cancel:
|
||||
msh_deallocate(cur_word_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
void msh_lexer_execute(msh_lexer *lexer) {
|
||||
msh_lexer_item_list *list = lexer->item_list_head;
|
||||
char *cmd = 0;
|
||||
char *cmd = list->item->str;
|
||||
SIZE_TYPE cmd_size = list->item->strlen;
|
||||
|
||||
SIZE_TYPE cmd_size = 0;
|
||||
SIZE_TYPE args_size = 0;
|
||||
char **args = 0;
|
||||
int is_first_arg = 0, i = 0, n = 0, j = 0, counter = 0, exec_success = 0;
|
||||
char *full_path;
|
||||
char is_first_arg = 0, exec_success = 0;
|
||||
unsigned short i = 0, n = 0, j = 0, counter = 0;
|
||||
char full_path[PATH_MAX];
|
||||
char *args[512];
|
||||
|
||||
while (list != 0) {
|
||||
if (!list->item) {
|
||||
break;
|
||||
}
|
||||
if (cmd == 0) {
|
||||
cmd = list->item->str;
|
||||
cmd_size = list->item->strlen;
|
||||
} else {
|
||||
args_size += 1;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
list = lexer->item_list_head;
|
||||
args = msh_allocate((args_size + 1) * sizeof(char *));
|
||||
while (list != 0) {
|
||||
if (!list->item) {
|
||||
break;
|
||||
|
|
@ -182,7 +163,6 @@ void msh_lexer_execute(msh_lexer *lexer) {
|
|||
/* loop through all the path entries and check if the file exists in them.
|
||||
*/
|
||||
i = 0, n = 0, j = 0;
|
||||
full_path = msh_allocate(1024);
|
||||
while (1) {
|
||||
full_path[n++] = lexer->path[j];
|
||||
if (lexer->path[j] == '\0') {
|
||||
|
|
@ -209,14 +189,11 @@ void msh_lexer_execute(msh_lexer *lexer) {
|
|||
}
|
||||
j++;
|
||||
}
|
||||
msh_deallocate(full_path);
|
||||
}
|
||||
if (!exec_success) {
|
||||
msh_print_strings("msh: ", cmd, ": command not found\n\r", 0);
|
||||
}
|
||||
|
||||
msh_deallocate(args);
|
||||
|
||||
msh_lexer_flush(lexer);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,13 @@ typedef struct msh_lexer_item_list_t {
|
|||
struct msh_lexer_item_list_t *next;
|
||||
} msh_lexer_item_list;
|
||||
|
||||
typedef struct msh_lexer_t msh_lexer;
|
||||
typedef struct msh_lexer_t {
|
||||
msh_lexer_item_list *item_list_head;
|
||||
msh_lexer_item_list *item_list_cur;
|
||||
char *path;
|
||||
} msh_lexer;
|
||||
|
||||
msh_lexer *msh_lexer_new();
|
||||
msh_lexer msh_lexer_new();
|
||||
void msh_lexer_parse(msh_lexer *lexer, char *buf, SIZE_TYPE sz);
|
||||
void msh_lexer_push_item(msh_lexer *lexer, msh_lexer_item_type type, char *buf,
|
||||
SIZE_TYPE strlen);
|
||||
|
|
|
|||
14
src/main.c
14
src/main.c
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
/* Makefile-defined system entry point. */
|
||||
MSH_ENTRY_POINT {
|
||||
msh_lexer *lexer;
|
||||
msh_lexer lexer;
|
||||
|
||||
msh_backend_init();
|
||||
|
||||
|
|
@ -11,10 +11,12 @@ MSH_ENTRY_POINT {
|
|||
|
||||
while (1) {
|
||||
int out;
|
||||
char *buf = msh_callocate(513, sizeof(char));
|
||||
char buf[513];
|
||||
int i = 0, n = 0, last = 0;
|
||||
SIZE_TYPE sz = 0, leftoff = 0;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
msh_print_strings(msh_working_directory(), " %> ", 0);
|
||||
|
||||
while ((out = msh_read_input(buf, &sz, 512)), out != -1) {
|
||||
|
|
@ -64,17 +66,17 @@ MSH_ENTRY_POINT {
|
|||
buf[sz] = '\0';
|
||||
|
||||
if (*buf != '\0') {
|
||||
msh_lexer_parse(lexer, buf, sz + 1);
|
||||
msh_lexer_execute(lexer);
|
||||
msh_lexer_parse(&lexer, buf, sz + 1);
|
||||
msh_lexer_execute(&lexer);
|
||||
}
|
||||
|
||||
// msh_execute(buf, args);
|
||||
|
||||
end_loop:
|
||||
msh_deallocate(buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
msh_lexer_free(lexer);
|
||||
msh_lexer_free(&lexer);
|
||||
|
||||
msh_backend_deinit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "../system.h"
|
||||
#include "syscall.h"
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct msh_linux_block_t msh_linux_block;
|
||||
|
||||
#ifdef ARCH_32
|
||||
|
|
@ -10,14 +11,13 @@ typedef struct msh_linux_block_t msh_linux_block;
|
|||
#endif
|
||||
|
||||
struct msh_linux_block_t {
|
||||
SIZE_TYPE size;
|
||||
int size;
|
||||
msh_linux_block *prev;
|
||||
msh_linux_block *next;
|
||||
int free;
|
||||
unsigned char free;
|
||||
char data[1];
|
||||
};
|
||||
|
||||
#define MSH_BLOCK_SIZE 28
|
||||
#define MSH_BLOCK_SIZE 21
|
||||
|
||||
static msh_linux_block *msh_linux_base = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,23 @@
|
|||
#include "../system.h"
|
||||
#include "linux.h"
|
||||
#include <linux/limits.h>
|
||||
|
||||
msh_linux_env_item *env_items = 0;
|
||||
msh_linux_env_item env_items;
|
||||
msh_linux_env_item *env_item_tail = 0;
|
||||
|
||||
void msh_linux_env_map_init() {
|
||||
msh_file *env_file = 0;
|
||||
msh_file env_file;
|
||||
SIZE_TYPE cur = 0;
|
||||
char *file_buf = 0;
|
||||
char file_buf[PATH_MAX];
|
||||
char ch = 1;
|
||||
int counter = 0, i = 0;
|
||||
|
||||
if (!env_items) {
|
||||
env_items = msh_callocate(1, sizeof(msh_linux_env_item));
|
||||
}
|
||||
env_item_tail = env_items;
|
||||
env_item_tail = &env_items;
|
||||
|
||||
env_file = msh_file_open("/proc/self/environ");
|
||||
file_buf = msh_callocate(512, sizeof(char));
|
||||
|
||||
while (1) {
|
||||
msh_file_read(env_file, &ch, 1);
|
||||
while (cur < PATH_MAX) {
|
||||
msh_file_read(&env_file, &ch, 1);
|
||||
|
||||
if (ch != '=') {
|
||||
file_buf[cur++] = ch;
|
||||
|
|
@ -29,6 +26,8 @@ void msh_linux_env_map_init() {
|
|||
}
|
||||
|
||||
if (ch == '=') {
|
||||
/* the potentially small allocations made here are fine because these last
|
||||
* the lifetime of the program and aren't freed either way */
|
||||
env_item_tail->key = msh_allocate(cur);
|
||||
msh_str_copy_str(env_item_tail->key, file_buf);
|
||||
env_item_tail->key_len = cur;
|
||||
|
|
@ -36,12 +35,16 @@ void msh_linux_env_map_init() {
|
|||
if (env_item_tail->key_hash == str_hash("PATH")) {
|
||||
env_item_tail->is_path = 1;
|
||||
}
|
||||
for (i = 0; i < cur; i++) {
|
||||
file_buf[i] = 0;
|
||||
}
|
||||
memset(file_buf, 0, sizeof(file_buf));
|
||||
|
||||
cur = 0;
|
||||
} else if (ch == '\0') {
|
||||
env_item_tail->value = file_buf;
|
||||
/* see comment above the env_item_tail->key comment */
|
||||
env_item_tail->value = msh_allocate(cur);
|
||||
for (i = 0; file_buf[i] && i < cur; i++) {
|
||||
env_item_tail->value[i] = file_buf[i];
|
||||
}
|
||||
|
||||
env_item_tail->value_len = cur;
|
||||
env_item_tail->next = msh_callocate(1, sizeof(msh_linux_env_item));
|
||||
|
||||
|
|
@ -50,7 +53,7 @@ void msh_linux_env_map_init() {
|
|||
file_buf[cur++] = '\0';
|
||||
}
|
||||
|
||||
file_buf = msh_callocate(512, sizeof(char));
|
||||
memset(file_buf, 0, sizeof(file_buf));
|
||||
cur = 0;
|
||||
env_item_tail = env_item_tail->next;
|
||||
|
||||
|
|
@ -64,14 +67,12 @@ void msh_linux_env_map_init() {
|
|||
}
|
||||
}
|
||||
|
||||
msh_deallocate(file_buf);
|
||||
|
||||
msh_file_close(env_file);
|
||||
msh_file_close(&env_file);
|
||||
};
|
||||
void msh_linux_env_map_deinit() {};
|
||||
|
||||
const char *msh_env_get(const char *key) {
|
||||
msh_linux_env_item *env_item_tail = env_items;
|
||||
msh_linux_env_item *env_item_tail = &env_items;
|
||||
int hash = str_hash((char *)key);
|
||||
|
||||
while (env_item_tail->next != 0) {
|
||||
|
|
@ -85,7 +86,7 @@ const char *msh_env_get(const char *key) {
|
|||
};
|
||||
|
||||
char *msh_env_get_path() {
|
||||
msh_linux_env_item *env_item_tail = env_items;
|
||||
msh_linux_env_item *env_item_tail = &env_items;
|
||||
|
||||
while (env_item_tail->next != 0) {
|
||||
if (env_item_tail->is_path) {
|
||||
|
|
@ -110,7 +111,7 @@ void msh_env_set(const char *key, char *value) {
|
|||
int hash = str_hash((char *)key);
|
||||
int env_was_set = 0;
|
||||
int key_size = 0, value_size = 0;
|
||||
msh_linux_env_item *env_item_local_cur = env_items;
|
||||
msh_linux_env_item *env_item_local_cur = &env_items;
|
||||
char ch = value[0];
|
||||
|
||||
while (ch != '\0') {
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ static const char *error_table[] = {
|
|||
"Memory page has hardware error"};
|
||||
|
||||
void msh_linux_print_errno(int errno) {
|
||||
char *errno_num_str = msh_allocate(64);
|
||||
char errno_num_str[16];
|
||||
itoa(errno, errno_num_str, 10);
|
||||
if (errno - 1 >= sizeof(error_table)) {
|
||||
msh_print_strings("Unknown error (errno ", errno_num_str, ")", 0);
|
||||
|
|
@ -145,5 +145,4 @@ void msh_linux_print_errno(int errno) {
|
|||
msh_print_strings("Error ", errno_num_str, " (", error_table[errno - 1],
|
||||
")", 0);
|
||||
}
|
||||
msh_deallocate(errno_num_str);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "syscall.h"
|
||||
|
||||
#include <linux/kd.h>
|
||||
#include <linux/limits.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/resource.h>
|
||||
|
|
@ -80,17 +81,10 @@ int msh_execute(char *cmd, char **args) {
|
|||
fork = (SIZE_TYPE)SYSCALL(fork, 0);
|
||||
|
||||
if (fork == 0) {
|
||||
const char **env_translated = 0;
|
||||
SIZE_TYPE env_translated_size = 0;
|
||||
static char *env_translated[PATH_MAX];
|
||||
SIZE_TYPE ret, i = 0, n = 0;
|
||||
msh_linux_env_item *item_list = env_items;
|
||||
while (item_list->next != 0) {
|
||||
env_translated_size += 1;
|
||||
item_list = item_list->next;
|
||||
}
|
||||
item_list = env_items;
|
||||
msh_linux_env_item *item_list = &env_items;
|
||||
|
||||
env_translated = msh_callocate(env_translated_size + 1, sizeof(char *));
|
||||
while (item_list != 0) {
|
||||
if (item_list->key != 0) {
|
||||
int n = 0;
|
||||
|
|
@ -111,7 +105,6 @@ int msh_execute(char *cmd, char **args) {
|
|||
for (n = 0; n < i; n++) {
|
||||
msh_deallocate(env_translated[n]);
|
||||
}
|
||||
msh_deallocate(env_translated);
|
||||
|
||||
if (ret == -2) {
|
||||
return -1;
|
||||
|
|
@ -144,14 +137,14 @@ void msh_exit_shell() {
|
|||
SYSCALL(exit, 0);
|
||||
};
|
||||
|
||||
msh_file *msh_file_open(const char *file) {
|
||||
msh_file *f = msh_allocate(sizeof(struct msh_file_t));
|
||||
msh_file msh_file_open(const char *file) {
|
||||
msh_file f;
|
||||
|
||||
f->fd = (int)(SIZE_TYPE)SYSCALL(open, file, O_RDONLY);
|
||||
f.__fd = (int)(SIZE_TYPE)SYSCALL(open, file, O_RDONLY);
|
||||
|
||||
if (f->fd < 0) {
|
||||
if (f.__fd < 0) {
|
||||
msh_print_strings("Error opening ", file, ": ", 0);
|
||||
msh_linux_print_errno(f->fd * -1);
|
||||
msh_linux_print_errno(f.__fd * -1);
|
||||
msh_print_string("\n");
|
||||
|
||||
msh_exit_shell();
|
||||
|
|
@ -161,23 +154,23 @@ msh_file *msh_file_open(const char *file) {
|
|||
};
|
||||
|
||||
void msh_file_close(msh_file *file) {
|
||||
SYSCALL(close, file->fd);
|
||||
SYSCALL(close, file->__fd);
|
||||
|
||||
msh_deallocate(file);
|
||||
};
|
||||
|
||||
void msh_file_read(msh_file *file, char *ptr, SIZE_TYPE n) {
|
||||
SYSCALL(read, file->fd, ptr, n);
|
||||
SYSCALL(read, file->__fd, ptr, n);
|
||||
};
|
||||
|
||||
SIZE_TYPE msh_file_size(msh_file *file) {
|
||||
SIZE_TYPE sz;
|
||||
|
||||
SYSCALL(lseek, file->fd, 0, SEEK_END);
|
||||
SYSCALL(lseek, file->__fd, 0, SEEK_END);
|
||||
|
||||
sz = (SIZE_TYPE)SYSCALL(lseek, file->fd, 0, SEEK_CUR);
|
||||
sz = (SIZE_TYPE)SYSCALL(lseek, file->__fd, 0, SEEK_CUR);
|
||||
|
||||
SYSCALL(lseek, file->fd, 0, SEEK_SET);
|
||||
SYSCALL(lseek, file->__fd, 0, SEEK_SET);
|
||||
|
||||
return sz;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,10 +13,7 @@ void msh_linux_end_input_capture();
|
|||
|
||||
void msh_linux_setup_signals();
|
||||
|
||||
struct msh_file_t {
|
||||
int fd;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct msh_linux_env_item_t msh_linux_env_item;
|
||||
struct msh_linux_env_item_t {
|
||||
char *key;
|
||||
|
|
@ -27,6 +24,8 @@ struct msh_linux_env_item_t {
|
|||
int is_path;
|
||||
msh_linux_env_item *next;
|
||||
};
|
||||
extern msh_linux_env_item *env_items;
|
||||
#pragma pack(pop)
|
||||
|
||||
extern msh_linux_env_item env_items;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -25,12 +25,16 @@ void msh_deallocate(void *ptr);
|
|||
void msh_exit_shell();
|
||||
|
||||
/* File given by the file functions */
|
||||
typedef struct msh_file_t msh_file;
|
||||
typedef struct msh_file_t {
|
||||
#ifdef __linux__
|
||||
int __fd;
|
||||
#endif
|
||||
} msh_file;
|
||||
|
||||
/*
|
||||
* Open the given file
|
||||
*/
|
||||
msh_file *msh_file_open(const char *file);
|
||||
msh_file msh_file_open(const char *file);
|
||||
|
||||
/*
|
||||
* Close the given file
|
||||
|
|
|
|||
|
|
@ -82,3 +82,10 @@ int itoa(int value, char *sp, int radix) {
|
|||
|
||||
return len;
|
||||
}
|
||||
SIZE_TYPE strlen(char *str) {
|
||||
SIZE_TYPE i = 0;
|
||||
while (*str++) {
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ void msh_print_string(char *str);
|
|||
/* Hash string */
|
||||
unsigned long str_hash(char *str);
|
||||
|
||||
SIZE_TYPE strlen(char *str);
|
||||
|
||||
/* satisfy glibc */
|
||||
void *memset(void *b, int c, SIZE_TYPE len);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue