Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Created by tools/inliner - DO NOT EDIT. */
- void __c(char *src) {
- for (int i = 0; src[i]; i++)
- SOURCE[source_idx++] = src[i];
- }
- void libc_generate() {
- __c("/*
- \n");
- __c(" * shecc - Self-Hosting and Educational C Compiler.
- \n");
- __c(" *
- \n");
- __c(" * shecc is freely redistributable under the BSD 2 clause license. See the
- \n");
- __c(" * file \"LICENSE\" for information on usage and redistribution of this file.
- \n");
- __c(" */
- \n");
- __c("
- \n");
- __c("/* minimal libc implementation */
- \n");
- __c("
- \n");
- __c("#define NULL 0
- \n");
- __c("
- \n");
- __c("#define bool _Bool
- \n");
- __c("#define true 1
- \n");
- __c("#define false 0
- \n");
- __c("
- \n");
- __c("#if defined(__arm__)
- \n");
- __c("#define __syscall_exit 1
- \n");
- __c("#define __syscall_read 3
- \n");
- __c("#define __syscall_write 4
- \n");
- __c("#define __syscall_close 6
- \n");
- __c("#define __syscall_open 5
- \n");
- __c("#define __syscall_mmap2 192
- \n");
- __c("#define __syscall_munmap 91
- \n");
- __c("
- \n");
- __c("#elif defined(__riscv)
- \n");
- __c("#define __syscall_exit 93
- \n");
- __c("#define __syscall_read 63
- \n");
- __c("#define __syscall_write 64
- \n");
- __c("#define __syscall_close 57
- \n");
- __c("#define __syscall_open 1024
- \n");
- __c("#define __syscall_openat 56
- \n");
- __c("#define __syscall_mmap2 222
- \n");
- __c("#define __syscall_munmap 215
- \n");
- __c("
- \n");
- __c("#else /* Only Arm32 and RV32 are supported */
- \n");
- __c("#error \"Unsupported architecture\"
- \n");
- __c("#endif
- \n");
- __c("
- \n");
- __c("#define INT_BUF_LEN 16
- \n");
- __c("
- \n");
- __c("typedef int FILE;
- \n");
- __c("
- \n");
- __c("void abort();
- \n");
- __c("
- \n");
- __c("int strlen(char *str)
- \n");
- __c("{
- \n");
- __c(" int i = 0;
- \n");
- __c(" while (str[i])
- \n");
- __c(" i++;
- \n");
- __c(" return i;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("int strcmp(char *s1, char *s2)
- \n");
- __c("{
- \n");
- __c(" int i = 0;
- \n");
- __c(" while (s1[i] && s2[i]) {
- \n");
- __c(" if (s1[i] < s2[i])
- \n");
- __c(" return -1;
- \n");
- __c(" if (s1[i] > s2[i])
- \n");
- __c(" return 1;
- \n");
- __c(" i++;
- \n");
- __c(" }
- \n");
- __c(" return s1[i] - s2[i];
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("int strncmp(char *s1, char *s2, int len)
- \n");
- __c("{
- \n");
- __c(" int i = 0;
- \n");
- __c(" while (i < len) {
- \n");
- __c(" if (s1[i] < s2[i])
- \n");
- __c(" return -1;
- \n");
- __c(" if (s1[i] > s2[i])
- \n");
- __c(" return 1;
- \n");
- __c(" i++;
- \n");
- __c(" }
- \n");
- __c(" return 0;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("char *strcpy(char *dest, char *src)
- \n");
- __c("{
- \n");
- __c(" int i = 0;
- \n");
- __c(" while (src[i]) {
- \n");
- __c(" dest[i] = src[i];
- \n");
- __c(" i++;
- \n");
- __c(" }
- \n");
- __c(" dest[i] = 0;
- \n");
- __c(" return dest;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("char *strncpy(char *dest, char *src, int len)
- \n");
- __c("{
- \n");
- __c(" int i = 0;
- \n");
- __c(" int beyond = 0;
- \n");
- __c(" while (i < len) {
- \n");
- __c(" if (beyond == 0) {
- \n");
- __c(" dest[i] = src[i];
- \n");
- __c(" if (src[i] == 0)
- \n");
- __c(" beyond = 1;
- \n");
- __c(" } else {
- \n");
- __c(" dest[i] = 0;
- \n");
- __c(" }
- \n");
- __c(" i++;
- \n");
- __c(" }
- \n");
- __c(" return dest;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("char *memcpy(char *dest, char *src, int count)
- \n");
- __c("{
- \n");
- __c(" while (count > 0) {
- \n");
- __c(" count--;
- \n");
- __c(" dest[count] = src[count];
- \n");
- __c(" }
- \n");
- __c(" return dest;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("/* set 10 digits (32bit) without div */
- \n");
- __c("void __str_base10(char *pb, int val)
- \n");
- __c("{
- \n");
- __c(" int neg = 0;
- \n");
- __c("
- \n");
- __c(" if (val == -2147483648) {
- \n");
- __c(" strncpy(pb + INT_BUF_LEN - 11, \"-2147483648\", 11);
- \n");
- __c(" return;
- \n");
- __c(" }
- \n");
- __c(" if (val < 0) {
- \n");
- __c(" neg = 1;
- \n");
- __c(" val = -val;
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" while (val >= 1000000000) {
- \n");
- __c(" val -= 1000000000;
- \n");
- __c(" pb[INT_BUF_LEN - 10]++;
- \n");
- __c(" }
- \n");
- __c(" while (val >= 100000000) {
- \n");
- __c(" val -= 100000000;
- \n");
- __c(" pb[INT_BUF_LEN - 9]++;
- \n");
- __c(" }
- \n");
- __c(" while (val >= 10000000) {
- \n");
- __c(" val -= 10000000;
- \n");
- __c(" pb[INT_BUF_LEN - 8]++;
- \n");
- __c(" }
- \n");
- __c(" while (val >= 1000000) {
- \n");
- __c(" val -= 1000000;
- \n");
- __c(" pb[INT_BUF_LEN - 7]++;
- \n");
- __c(" }
- \n");
- __c(" while (val >= 100000) {
- \n");
- __c(" val -= 100000;
- \n");
- __c(" pb[INT_BUF_LEN - 6]++;
- \n");
- __c(" }
- \n");
- __c(" while (val >= 10000) {
- \n");
- __c(" val -= 10000;
- \n");
- __c(" pb[INT_BUF_LEN - 5]++;
- \n");
- __c(" }
- \n");
- __c(" while (val >= 1000) {
- \n");
- __c(" val -= 1000;
- \n");
- __c(" pb[INT_BUF_LEN - 4]++;
- \n");
- __c(" }
- \n");
- __c(" while (val >= 100) {
- \n");
- __c(" val -= 100;
- \n");
- __c(" pb[INT_BUF_LEN - 3]++;
- \n");
- __c(" }
- \n");
- __c(" while (val >= 10) {
- \n");
- __c(" val -= 10;
- \n");
- __c(" pb[INT_BUF_LEN - 2]++;
- \n");
- __c(" }
- \n");
- __c(" while (val >= 1) {
- \n");
- __c(" val -= 1;
- \n");
- __c(" pb[INT_BUF_LEN - 1]++;
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" if (neg == 1) {
- \n");
- __c(" int c = 0;
- \n");
- __c(" while (pb[c] == '0')
- \n");
- __c(" c++;
- \n");
- __c(" if (c > 0)
- \n");
- __c(" pb[c - 1] = '-';
- \n");
- __c(" }
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("void __str_base8(char *pb, int val)
- \n");
- __c("{
- \n");
- __c(" int c = INT_BUF_LEN - 1;
- \n");
- __c(" while (c > 0) {
- \n");
- __c(" int v = val & 0x7;
- \n");
- __c(" pb[c] = '0' + v;
- \n");
- __c(" val = val >> 3;
- \n");
- __c(" c--;
- \n");
- __c(" }
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("void __str_base16(char *pb, int val)
- \n");
- __c("{
- \n");
- __c(" int c = INT_BUF_LEN - 1;
- \n");
- __c(" while (c > 0) {
- \n");
- __c(" int v = val & 0xf;
- \n");
- __c(" if (v < 10)
- \n");
- __c(" pb[c] = '0' + v;
- \n");
- __c(" else if (v < 16)
- \n");
- __c(" pb[c] = 'a' + v - 10;
- \n");
- __c(" else {
- \n");
- __c(" abort();
- \n");
- __c(" break;
- \n");
- __c(" }
- \n");
- __c(" val = val >> 4;
- \n");
- __c(" c--;
- \n");
- __c(" }
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("int __format(char *buffer,
- \n");
- __c(" int val,
- \n");
- __c(" int width,
- \n");
- __c(" int zeropad,
- \n");
- __c(" int base,
- \n");
- __c(" int alternate_form)
- \n");
- __c("{
- \n");
- __c(" int bi = 0;
- \n");
- __c(" char pb[INT_BUF_LEN];
- \n");
- __c(" int pbi = 0;
- \n");
- __c("
- \n");
- __c(" if (alternate_form == 1) {
- \n");
- __c(" switch (base) {
- \n");
- __c(" case 8:
- \n");
- __c(" /* octal */
- \n");
- __c(" buffer[0] = '0';
- \n");
- __c(" bi = 1;
- \n");
- __c(" width -= 1;
- \n");
- __c(" break;
- \n");
- __c(" case 16:
- \n");
- __c(" /* hex */
- \n");
- __c(" buffer[0] = '0';
- \n");
- __c(" buffer[1] = 'x';
- \n");
- __c(" bi = 2;
- \n");
- __c(" width -= 2;
- \n");
- __c(" break;
- \n");
- __c(" default:
- \n");
- __c(" /* decimal */
- \n");
- __c(" /* do nothing */
- \n");
- __c(" break;
- \n");
- __c(" }
- \n");
- __c(" if (width < 0)
- \n");
- __c(" width = 0;
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" /* set to zeroes */
- \n");
- __c(" while (pbi < INT_BUF_LEN) {
- \n");
- __c(" pb[pbi] = '0';
- \n");
- __c(" pbi++;
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" switch (base) {
- \n");
- __c(" case 8:
- \n");
- __c(" __str_base8(pb, val);
- \n");
- __c(" break;
- \n");
- __c(" case 10:
- \n");
- __c(" __str_base10(pb, val);
- \n");
- __c(" break;
- \n");
- __c(" case 16:
- \n");
- __c(" __str_base16(pb, val);
- \n");
- __c(" break;
- \n");
- __c(" default:
- \n");
- __c(" abort();
- \n");
- __c(" break;
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" while (width > INT_BUF_LEN) {
- \n");
- __c(" /* need to add extra padding */
- \n");
- __c(" if (zeropad == 1)
- \n");
- __c(" buffer[bi] = '0';
- \n");
- __c(" else
- \n");
- __c(" buffer[bi] = ' ';
- \n");
- __c(" bi++;
- \n");
- __c(" width--;
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" /* no padding */
- \n");
- __c(" if (width == 0) {
- \n");
- __c(" int c = 0;
- \n");
- __c(" int started = 0;
- \n");
- __c("
- \n");
- __c(" /* output from first digit */
- \n");
- __c(" while (c < INT_BUF_LEN) {
- \n");
- __c(" if (pb[c] != '0')
- \n");
- __c(" started = 1;
- \n");
- __c(" if (started) {
- \n");
- __c(" buffer[bi] = pb[c];
- \n");
- __c(" bi++;
- \n");
- __c(" }
- \n");
- __c(" c++;
- \n");
- __c(" }
- \n");
- __c(" /* special case - zero */
- \n");
- __c(" if (started == 0) {
- \n");
- __c(" buffer[bi] = '0';
- \n");
- __c(" bi++;
- \n");
- __c(" }
- \n");
- __c(" } else {
- \n");
- __c(" /* padding */
- \n");
- __c(" int c = INT_BUF_LEN - width;
- \n");
- __c(" int started = 0;
- \n");
- __c(" while (c < INT_BUF_LEN) {
- \n");
- __c(" if (pb[c] != '0')
- \n");
- __c(" started = 1;
- \n");
- __c(" if (started)
- \n");
- __c(" buffer[bi] = pb[c];
- \n");
- __c(" else if (zeropad == 1)
- \n");
- __c(" buffer[bi] = '0';
- \n");
- __c(" else
- \n");
- __c(" buffer[bi] = ' ';
- \n");
- __c(" bi++;
- \n");
- __c(" c++;
- \n");
- __c(" }
- \n");
- __c(" }
- \n");
- __c(" return bi;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("void printf(char *str, ...)
- \n");
- __c("{
- \n");
- __c(" int *var_args = &str + 4;
- \n");
- __c(" char buffer[200];
- \n");
- __c(" int si = 0, bi = 0, pi = 0;
- \n");
- __c("
- \n");
- __c(" while (str[si]) {
- \n");
- __c(" if (str[si] != '%') {
- \n");
- __c(" buffer[bi] = str[si];
- \n");
- __c(" bi++;
- \n");
- __c(" si++;
- \n");
- __c(" } else {
- \n");
- __c(" int w = 0, zp = 0, pp = 0;
- \n");
- __c("
- \n");
- __c(" si++;
- \n");
- __c(" if (str[si] == '#') {
- \n");
- __c(" pp = 1;
- \n");
- __c(" si++;
- \n");
- __c(" }
- \n");
- __c(" if (str[si] == '0') {
- \n");
- __c(" zp = 1;
- \n");
- __c(" si++;
- \n");
- __c(" }
- \n");
- __c(" if (str[si] >= '1' && str[si] <= '9') {
- \n");
- __c(" w = str[si] - '0';
- \n");
- __c(" si++;
- \n");
- __c(" while (str[si] >= '0' && str[si] <= '9') {
- \n");
- __c(" w = w * 10;
- \n");
- __c(" w += str[si] - '0';
- \n");
- __c(" si++;
- \n");
- __c(" }
- \n");
- __c(" }
- \n");
- __c(" if (str[si] == 's') {
- \n");
- __c(" /* append param pi as string */
- \n");
- __c(" int l = strlen(var_args[pi]);
- \n");
- __c(" strcpy(buffer + bi, var_args[pi]);
- \n");
- __c(" bi += l;
- \n");
- __c(" } else if (str[si] == 'c') {
- \n");
- __c(" /* append param pi as char */
- \n");
- __c(" buffer[bi] = var_args[pi];
- \n");
- __c(" bi += 1;
- \n");
- __c(" } else if (str[si] == 'o') {
- \n");
- __c(" /* append param as octal */
- \n");
- __c(" int v = var_args[pi];
- \n");
- __c(" bi += __format(buffer + bi, v, w, zp, 8, pp);
- \n");
- __c(" } else if (str[si] == 'd') {
- \n");
- __c(" /* append param as decimal */
- \n");
- __c(" int v = var_args[pi];
- \n");
- __c(" bi += __format(buffer + bi, v, w, zp, 10, 0);
- \n");
- __c(" } else if (str[si] == 'x') {
- \n");
- __c(" /* append param as hex */
- \n");
- __c(" int v = var_args[pi];
- \n");
- __c(" bi += __format(buffer + bi, v, w, zp, 16, pp);
- \n");
- __c(" } else if (str[si] == '%') {
- \n");
- __c(" /* append literal '%' character */
- \n");
- __c(" buffer[bi] = '%';
- \n");
- __c(" bi++;
- \n");
- __c(" si++;
- \n");
- __c(" continue;
- \n");
- __c(" }
- \n");
- __c(" pi++;
- \n");
- __c(" si++;
- \n");
- __c(" }
- \n");
- __c(" }
- \n");
- __c(" buffer[bi] = 0;
- \n");
- __c(" __syscall(__syscall_write, 1, buffer, bi);
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("void sprintf(char *buffer, char *str, ...)
- \n");
- __c("{
- \n");
- __c(" int *var_args = &str + 4;
- \n");
- __c(" int si = 0, bi = 0, pi = 0;
- \n");
- __c("
- \n");
- __c(" while (str[si]) {
- \n");
- __c(" if (str[si] != '%') {
- \n");
- __c(" buffer[bi] = str[si];
- \n");
- __c(" bi++;
- \n");
- __c(" si++;
- \n");
- __c(" } else {
- \n");
- __c(" int w = 0, zp = 0, pp = 0;
- \n");
- __c("
- \n");
- __c(" si++;
- \n");
- __c(" if (str[si] == '#') {
- \n");
- __c(" pp = 1;
- \n");
- __c(" si++;
- \n");
- __c(" }
- \n");
- __c(" if (str[si] == '0') {
- \n");
- __c(" zp = 1;
- \n");
- __c(" si++;
- \n");
- __c(" }
- \n");
- __c(" if (str[si] >= '1' && str[si] <= '9') {
- \n");
- __c(" w = str[si] - '0';
- \n");
- __c(" si++;
- \n");
- __c(" if (str[si] >= '0' && str[si] <= '9') {
- \n");
- __c(" w = w * 10;
- \n");
- __c(" w += str[si] - '0';
- \n");
- __c(" si++;
- \n");
- __c(" }
- \n");
- __c(" }
- \n");
- __c(" switch (str[si]) {
- \n");
- __c(" case 37: /* % */
- \n");
- __c(" buffer[bi++] = '%';
- \n");
- __c(" si++;
- \n");
- __c(" continue;
- \n");
- __c(" case 99: /* c */
- \n");
- __c(" buffer[bi++] = var_args[pi];
- \n");
- __c(" break;
- \n");
- __c(" case 115: /* s */
- \n");
- __c(" strcpy(buffer + bi, var_args[pi]);
- \n");
- __c(" bi += strlen(var_args[pi]);
- \n");
- __c(" break;
- \n");
- __c(" case 111: /* o */
- \n");
- __c(" bi += __format(buffer + bi, var_args[pi], w, zp, 8, pp);
- \n");
- __c(" break;
- \n");
- __c(" case 100: /* d */
- \n");
- __c(" bi += __format(buffer + bi, var_args[pi], w, zp, 10, 0);
- \n");
- __c(" break;
- \n");
- __c(" case 120: /* x */
- \n");
- __c(" bi += __format(buffer + bi, var_args[pi], w, zp, 16, pp);
- \n");
- __c(" break;
- \n");
- __c(" default:
- \n");
- __c(" abort();
- \n");
- __c(" break;
- \n");
- __c(" }
- \n");
- __c(" pi++;
- \n");
- __c(" si++;
- \n");
- __c(" }
- \n");
- __c(" }
- \n");
- __c(" buffer[bi] = 0;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("int __free_all();
- \n");
- __c("
- \n");
- __c("void exit(int exit_code)
- \n");
- __c("{
- \n");
- __c(" __free_all();
- \n");
- __c(" __syscall(__syscall_exit, exit_code);
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("void abort()
- \n");
- __c("{
- \n");
- __c(" printf(\"Abnormal program termination\n\");
- \n");
- __c(" exit(-1);
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("FILE *fopen(char *filename, char *mode)
- \n");
- __c("{
- \n");
- __c(" if (!strcmp(mode, \"wb\")) {
- \n");
- __c("#if defined(__arm__)
- \n");
- __c(" return __syscall(__syscall_open, filename, 65, 0x1fd);
- \n");
- __c("#elif defined(__riscv)
- \n");
- __c(" /* FIXME: mode not work currently in RISC-V */
- \n");
- __c(" return __syscall(__syscall_openat, -100, filename, 65, 0x1fd);
- \n");
- __c("#endif
- \n");
- __c(" }
- \n");
- __c(" if (!strcmp(mode, \"rb\")) {
- \n");
- __c("#if defined(__arm__)
- \n");
- __c(" return __syscall(__syscall_open, filename, 0, 0);
- \n");
- __c("#elif defined(__riscv)
- \n");
- __c(" return __syscall(__syscall_openat, -100, filename, 0, 0);
- \n");
- __c("#endif
- \n");
- __c(" }
- \n");
- __c(" return NULL;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("int fclose(FILE *stream)
- \n");
- __c("{
- \n");
- __c(" __syscall(__syscall_close, stream);
- \n");
- __c(" return 0;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("/* Read a byte from file descriptor. So the return value is either in the range
- \n");
- __c(" * of 0 to 127 for the character, or -1 on the end of file. */
- \n");
- __c("int fgetc(FILE *stream)
- \n");
- __c("{
- \n");
- __c(" int buf = 0, r = __syscall(__syscall_read, stream, &buf, 1);
- \n");
- __c(" if (r < 1)
- \n");
- __c(" return -1;
- \n");
- __c(" return buf;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("char *fgets(char *str, int n, FILE *stream)
- \n");
- __c("{
- \n");
- __c(" int i;
- \n");
- __c(" for (i = 0; i < n - 1; i++) {
- \n");
- __c(" int c = fgetc(stream);
- \n");
- __c(" if (c == -1) {
- \n");
- __c(" if (i == 0)
- \n");
- __c(" /* EOF on first char */
- \n");
- __c(" return NULL;
- \n");
- __c(" /* EOF in the middle */
- \n");
- __c(" str[i] = 0;
- \n");
- __c(" return str;
- \n");
- __c(" }
- \n");
- __c(" /* Not support casting yet. Simply assign it. */
- \n");
- __c(" str[i] = c;
- \n");
- __c("
- \n");
- __c(" if (c == '\n') {
- \n");
- __c(" str[i + 1] = 0;
- \n");
- __c(" return str;
- \n");
- __c(" }
- \n");
- __c(" }
- \n");
- __c(" str[i] = 0;
- \n");
- __c(" return str;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("int fputc(int c, FILE *stream)
- \n");
- __c("{
- \n");
- __c(" char buf[1];
- \n");
- __c(" buf[0] = c;
- \n");
- __c(" __syscall(__syscall_write, stream, buf, 1);
- \n");
- __c(" return 0;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("/* Non-portable: Assume page size is 4KiB */
- \n");
- __c("#define PAGESIZE 4096
- \n");
- __c("
- \n");
- __c("#define CHUNK_SIZE_FREED_MASK 1
- \n");
- __c("#define CHUNK_SIZE_SZ_MASK 0xFFFFFFFE
- \n");
- __c("#define CHUNK_GET_SIZE(size) (size & CHUNK_SIZE_SZ_MASK)
- \n");
- __c("#define IS_CHUNK_GET_FREED(size) (size & CHUNK_SIZE_FREED_MASK)
- \n");
- __c("
- \n");
- __c("typedef struct chunk {
- \n");
- __c(" struct chunk *next;
- \n");
- __c(" struct chunk *prev;
- \n");
- __c(" int size;
- \n");
- __c("} chunk_t;
- \n");
- __c("
- \n");
- __c("void chunk_set_freed(chunk_t *chunk)
- \n");
- __c("{
- \n");
- __c(" chunk->size |= CHUNK_SIZE_FREED_MASK;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("void chunk_clear_freed(chunk_t *chunk)
- \n");
- __c("{
- \n");
- __c(" chunk->size &= CHUNK_SIZE_SZ_MASK;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("int __align_up(int size)
- \n");
- __c("{
- \n");
- __c(" int mask = PAGESIZE - 1;
- \n");
- __c(" return ((size - 1) | mask) + 1;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("chunk_t *__alloc_head;
- \n");
- __c("chunk_t *__alloc_tail;
- \n");
- __c("chunk_t *__freelist_head;
- \n");
- __c("
- \n");
- __c("void *malloc(int size)
- \n");
- __c("{
- \n");
- __c(" if (size <= 0)
- \n");
- __c(" return NULL;
- \n");
- __c("
- \n");
- __c(" int flags = 34; /* MAP_PRIVATE (0x02) | MAP_ANONYMOUS (0x20) */
- \n");
- __c(" int prot = 3; /* PROT_READ (0x01) | PROT_WRITE (0x02) */
- \n");
- __c("
- \n");
- __c(" if (!__alloc_head) {
- \n");
- __c(" chunk_t *tmp =
- \n");
- __c(" __syscall(__syscall_mmap2, NULL, __align_up(sizeof(chunk_t)), prot,
- \n");
- __c(" flags, -1, 0);
- \n");
- __c(" __alloc_head = tmp;
- \n");
- __c(" __alloc_tail = tmp;
- \n");
- __c(" __alloc_head->next = NULL;
- \n");
- __c(" __alloc_head->prev = NULL;
- \n");
- __c(" __alloc_head->size = 0;
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" if (!__freelist_head) {
- \n");
- __c(" chunk_t *tmp =
- \n");
- __c(" __syscall(__syscall_mmap2, NULL, __align_up(sizeof(chunk_t)), prot,
- \n");
- __c(" flags, -1, 0);
- \n");
- __c(" __freelist_head = tmp;
- \n");
- __c(" __freelist_head->next = NULL;
- \n");
- __c(" __freelist_head->prev = NULL;
- \n");
- __c(" __freelist_head->size = -1;
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" /* to search the best chunk */
- \n");
- __c(" chunk_t *best_fit_chunk = NULL;
- \n");
- __c(" chunk_t *allocated;
- \n");
- __c("
- \n");
- __c(" if (!__freelist_head->next) {
- \n");
- __c(" /* If no more chunks in the free chunk list, allocate best_fit_chunk
- \n");
- __c(" * as NULL.
- \n");
- __c(" */
- \n");
- __c(" allocated = best_fit_chunk;
- \n");
- __c(" } else {
- \n");
- __c(" /* record the size of the chunk */
- \n");
- __c(" int bsize = 0;
- \n");
- __c("
- \n");
- __c(" for (chunk_t *fh = __freelist_head; fh->next; fh = fh->next) {
- \n");
- __c(" int fh_size = CHUNK_GET_SIZE(fh->size);
- \n");
- __c(" if (fh_size >= size && !best_fit_chunk) {
- \n");
- __c(" /* first time setting fh as best_fit_chunk */
- \n");
- __c(" best_fit_chunk = fh;
- \n");
- __c(" bsize = fh_size;
- \n");
- __c(" } else if ((fh_size >= size) && best_fit_chunk &&
- \n");
- __c(" (fh_size < bsize)) {
- \n");
- __c(" /* If there is a smaller chunk available, replace it. */
- \n");
- __c(" best_fit_chunk = fh;
- \n");
- __c(" bsize = fh_size;
- \n");
- __c(" }
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" /* a suitable chunk has been found */
- \n");
- __c(" if (best_fit_chunk) {
- \n");
- __c(" /* remove the chunk from the freelist */
- \n");
- __c(" if (best_fit_chunk->prev) {
- \n");
- __c(" chunk_t *tmp = best_fit_chunk->prev;
- \n");
- __c(" tmp->next = best_fit_chunk->next;
- \n");
- __c(" } else
- \n");
- __c(" __freelist_head = best_fit_chunk->next;
- \n");
- __c("
- \n");
- __c(" if (best_fit_chunk->next) {
- \n");
- __c(" chunk_t *tmp = best_fit_chunk->next;
- \n");
- __c(" tmp->prev = best_fit_chunk->prev;
- \n");
- __c(" }
- \n");
- __c(" }
- \n");
- __c(" allocated = best_fit_chunk;
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" if (!allocated) {
- \n");
- __c(" allocated =
- \n");
- __c(" __syscall(__syscall_mmap2, NULL, __align_up(sizeof(chunk_t) + size),
- \n");
- __c(" prot, flags, -1, 0);
- \n");
- __c(" allocated->size = __align_up(sizeof(chunk_t) + size);
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" __alloc_tail->next = allocated;
- \n");
- __c(" allocated->prev = __alloc_tail;
- \n");
- __c("
- \n");
- __c(" __alloc_tail = allocated;
- \n");
- __c(" __alloc_tail->next = NULL;
- \n");
- __c(" __alloc_tail->size = allocated->size;
- \n");
- __c(" chunk_clear_freed(__alloc_tail);
- \n");
- __c(" void *ptr = __alloc_tail + 1;
- \n");
- __c(" return ptr;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("void *calloc(int n, int size)
- \n");
- __c("{
- \n");
- __c(" char *p = malloc(n * size);
- \n");
- __c(" for (int i = 0; i < n * size; i++)
- \n");
- __c(" p[i] = 0;
- \n");
- __c(" return p;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("void __rfree(void *ptr, int size)
- \n");
- __c("{
- \n");
- __c(" if (!ptr)
- \n");
- __c(" return;
- \n");
- __c(" __syscall(__syscall_munmap, ptr, size);
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("int __free_all()
- \n");
- __c("{
- \n");
- __c(" if (!__freelist_head && !__alloc_head)
- \n");
- __c(" return 0;
- \n");
- __c("
- \n");
- __c(" chunk_t *cur = __freelist_head;
- \n");
- __c(" chunk_t *rel;
- \n");
- __c(" int size;
- \n");
- __c("
- \n");
- __c(" /* release freelist */
- \n");
- __c(" while (cur->next) {
- \n");
- __c(" rel = cur;
- \n");
- __c(" cur = cur->next;
- \n");
- __c(" rel->next = NULL;
- \n");
- __c(" rel->prev = NULL;
- \n");
- __c(" size = CHUNK_GET_SIZE(rel->size);
- \n");
- __c(" __rfree(rel, size);
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" if (__alloc_head->next) {
- \n");
- __c(" cur = __alloc_head->next;
- \n");
- __c(" /* release chunks which not be free */
- \n");
- __c(" while (cur) {
- \n");
- __c(" rel = cur;
- \n");
- __c(" cur = cur->next;
- \n");
- __c(" rel->next = NULL;
- \n");
- __c(" rel->prev = NULL;
- \n");
- __c(" size = CHUNK_GET_SIZE(rel->size);
- \n");
- __c(" __rfree(rel, size);
- \n");
- __c(" }
- \n");
- __c(" }
- \n");
- __c(" return 0;
- \n");
- __c("}
- \n");
- __c("
- \n");
- __c("void free(void *ptr)
- \n");
- __c("{
- \n");
- __c(" if (!ptr)
- \n");
- __c(" return;
- \n");
- __c("
- \n");
- __c(" char *__ptr = ptr;
- \n");
- __c(" chunk_t *cur = __ptr - sizeof(chunk_t);
- \n");
- __c(" if (IS_CHUNK_GET_FREED(cur->size)) {
- \n");
- __c(" printf(\"free(): double free detected\n\");
- \n");
- __c(" abort();
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" chunk_t *prev;
- \n");
- __c(" if (cur->prev) {
- \n");
- __c(" prev = cur->prev;
- \n");
- __c(" prev->next = cur->next;
- \n");
- __c(" } else
- \n");
- __c(" __alloc_head = cur->next;
- \n");
- __c("
- \n");
- __c(" if (cur->next) {
- \n");
- __c(" chunk_t *next = cur->next;
- \n");
- __c(" next->prev = cur->prev;
- \n");
- __c(" } else {
- \n");
- __c(" prev->next = NULL;
- \n");
- __c(" __alloc_tail = prev;
- \n");
- __c(" }
- \n");
- __c("
- \n");
- __c(" /* Insert head in __freelist_head */
- \n");
- __c(" cur->next = __freelist_head;
- \n");
- __c(" cur->prev = NULL;
- \n");
- __c(" chunk_set_freed(cur);
- \n");
- __c(" __freelist_head->prev = cur;
- \n");
- __c(" __freelist_head = cur;
- \n");
- __c("}
- \n");
- }
Advertisement
Add Comment
Please, Sign In to add comment