static void write_section(String *header, String *content, Section *sect, int offset) { o4(header, sect->shstrtab_off); // sh_name o4(header, sect->type); // sh_type o8(header, sect->flags); // sh_flags o8(header, 0); // sh_addr o8(header, STRING_LEN(content) + offset); // sh_offset o8(header, STRING_LEN(sect->body)); // sh_size o4(header, sect->link); // sh_link = SHN_UNDEF o4(header, sect->info); // sh_info o8(header, sect->align); // sh_addralign o8(header, sect->entsize); // sh_entsize out(content, STRING_BODY(sect->body), STRING_LEN(sect->body)); align(content, 16); }
static void add_symtab(Elf *elf) { String *symtabb = make_string(); String *strtabb = make_string(); o1(strtabb, 0); // Null symbol for (int i = 0; i < 24; i++) o1(symtabb, 0); // File symbol o4(symtabb, STRING_LEN(strtabb)); // st_name ostr(strtabb, "noname"); o1(symtabb, ELF64_ST_INFO(STB_LOCAL, STT_FILE)); // st_info o1(symtabb, 0); // other o2(symtabb, SHN_ABS); // st_shndx o8(symtabb, 0); // st_value o8(symtabb, 0); // st_size int index = 2; write_sym_to_buf(elf, &index, symtabb, strtabb, true); int localidx = index; write_section_sym(elf, &index, symtabb, strtabb); write_sym_to_buf(elf, &index, symtabb, strtabb, false); elf->symtabnum = LIST_LEN(elf->sections) + 1; Section *symtab = make_section(".symtab", SHT_SYMTAB); symtab->body = symtabb; symtab->link = LIST_LEN(elf->sections) + 2; symtab->info = localidx + 2; symtab->entsize = 24; symtab->align = 4; add_section(elf, symtab); Section *strtab = make_section(".strtab", SHT_STRTAB); strtab->body = strtabb; add_section(elf, strtab); }
/* * Join tokens in a given list. If sep is true, a space is put * between tokens. If false, no separator. */ static String *join_tokens(List *arg, bool sep) { String *s = make_string(); for (int i = 0; i < LIST_LEN(arg); i++) { Token *tok = LIST_REF(arg, i); if (sep && STRING_LEN(s) && tok->space) o1(s, ' '); switch (tok->toktype) { case TOKTYPE_IDENT: case TOKTYPE_CPPNUM: string_append(s, STRING_BODY(tok->val.str)); break; case TOKTYPE_PUNCT: string_append(s, token_to_string(tok)); break; case TOKTYPE_CHAR: { // TODO: retain original spelling o1(s, '\''); stringize_char(s, tok->val.i, '\''); string_append(s, "\'"); break; } case TOKTYPE_STRING: { o1(s, '"'); for (char *p = STRING_BODY(tok->val.str); *p; p++) stringize_char(s, *p, '\"'); string_append(s, "\""); break; } default: panic("invalid token type: %d", tok->toktype); } } return s; }
int stringComp(Object *ptr, Object *ptr2) { int len = STRING_LEN(ptr); int len2 = STRING_LEN(ptr2); if(len == len2) { int offset = STRING_OFFSET(ptr); int offset2 = STRING_OFFSET(ptr2); Object *array = INST_DATA(ptr, Object*, value_offset); Object *array2 = INST_DATA(ptr2, Object*, value_offset); unsigned short *src = ARRAY_DATA(array, unsigned short) + offset; unsigned short *dst = ARRAY_DATA(array2, unsigned short) + offset2; for(; (len > 0) && (*src++ == *dst++); len--); if(len == 0) return TRUE; }
/* * KodeSubj, handle PCBoard style long subjects lines in replies. * Note that sprintf() returns a char pointer under SunOS but * an integer under POSIX. Therefore for portability, char_cnt * must be calculated in a separate operation. */ static size_t KodeSubj(char CONSPTR tampbuf) { size_t text_start_offset = 0; char *long_subj = NULL ; /* if a long subject line was entered, format it PCBoard style */ if (PCBLONG && (long_subj = get_reply_lsubj()) != NULL) { byte CONSPTR net_flag = (byte *) tampbuf; char *buf_ptr = tampbuf; size_t char_cnt; /* write head string and subject to reply buffer */ sprintf(tampbuf, "%s%s", LSUBJ_HEAD, long_subj); free_string(long_subj); /* guarantee temination before taking length */ tampbuf[LSUBJ_HEAD_LEN + LSUBJ_BODY_LEN] = NUL_CHAR; char_cnt = strlen(tampbuf); buf_ptr += char_cnt; /* adjust for FIDO network if needed */ *net_flag = (byte) (fido ? SPC_CHAR : DOS_SPACE); /* pad message with space characters */ while (char_cnt < (size_t)(LSUBJ_HEAD_LEN + LSUBJ_LEN)) { *buf_ptr++ = SPC_CHAR; char_cnt++; } #ifdef ATPDBG assert((STRING_LEN(LSUBJ_HEAD) + STRING_LEN(LSUBJ_TAIL) + LSUBJ_LEN) == LSUBJ_BUF_LEN); assert(STRING_LEN(LSUBJ_HEAD) == 10); assert(STRING_LEN(LSUBJ_TAIL) == 8); assert(buf_ptr == (tampbuf + 64)); #endif strcpy(buf_ptr, LSUBJ_TAIL); strcat(buf_ptr, "\n"); text_start_offset = strlen(tampbuf); assert( text_start_offset == (LSUBJ_BUF_LEN + STRING_LEN("\n"))); } return text_start_offset; }
int stringHash(Object *ptr) { int len = STRING_LEN(ptr); int offset = STRING_OFFSET(ptr); Object *array = INST_DATA(ptr, Object*, value_offset); unsigned short *dpntr = ARRAY_DATA(array, unsigned short) + offset; int hash = 0; for(; len > 0; len--) hash = hash * 37 + *dpntr++; return hash; }
void write_elf(FILE *outfile, Elf *elf) { add_symtab(elf); add_reloc(elf); add_shstrtab(elf); // Section header String *sh = make_string(); for (int i = 0; i < 64; i++) o1(sh, 0); // NULL section header // Body String *content = make_string(); for (int i = 0; i < LIST_LEN(elf->sections); i++) { write_section(sh, content, LIST_REF(elf->sections, i), 64); } align(content, 16); // ELF header String *eh = make_string(); int numsect = LIST_LEN(elf->sections) + 1; out(eh, elf_ident, sizeof(elf_ident)); o2(eh, 1); // e_type = ET_REL o2(eh, 62); // e_machine = EM_X86_64 o4(eh, 1); // e_version = EV_CURRENT o8(eh, 0); // e_entry o8(eh, 0); // e_phoff o8(eh, STRING_LEN(content) + 64); // e_shoff; o4(eh, 0); // e_flags o2(eh, 64); // e_ehsize o2(eh, 0); // e_phentsize o2(eh, 0); // e_phnum o2(eh, 64); // e_shentsize o2(eh, numsect); // e_shnum o2(eh, elf->shnum); // e_shstrndx fwrite(STRING_BODY(eh), STRING_LEN(eh), 1, outfile); fwrite(STRING_BODY(content), STRING_LEN(content), 1, outfile); fwrite(STRING_BODY(sh), STRING_LEN(sh), 1, outfile); fclose(outfile); }
static void add_shstrtab(Elf *elf) { Section *shstr = make_section(".shstrtab", SHT_STRTAB); elf->shnum = LIST_LEN(elf->sections) + 1; add_section(elf, shstr); String *b = make_string(); o1(b, 0); for (int i = 0; i < LIST_LEN(elf->sections); i++) { Section *sect = LIST_REF(elf->sections, i); sect->shstrtab_off = STRING_LEN(b); ostr(b, sect->name); } shstr->body = b; }
static void write_one_symbol(Symbol *sym, int *index, String *symtab, String *strtab) { if (sym->name) { o4(symtab, STRING_LEN(strtab)); // st_name ostr(strtab, STRING_BODY(sym->name)); } else { o4(symtab, 0); // st_name } o1(symtab, ELF64_ST_INFO(sym->bind, sym->type)); // st_info; o1(symtab, 0); // st_other; if (sym->defined) { o2(symtab, sym->section->shndx); // st_shndx } else { o2(symtab, 0); // st_shndx } o8(symtab, sym->value); // st_value o8(symtab, 0); // st_size sym->index = (*index)++; }
object_t *kernel_require(static_context_t *this_context, object_t *self, object_t *filename_obj) { object_t *filename_str = coerce_to_s(this_context, filename_obj); char *filename = STRING_PTR(filename_str); int i; for (i = 0; i < ARRAY_LEN(load_path); i++) { char *path = STRING_PTR(coerce_to_s(this_context, ARRAY_PTR(load_path)[i])); char buf[strlen(path) + STRING_LEN(filename_str) + 10]; sprintf(buf, "%s/%s.rb", path, filename); FILE *file = fopen(buf, "rb"); if (!file) continue; fclose(file); /* we've found the file */ kernel_load(this_context, self, string_new_cstr(buf)); return Qnil; } raise(LoadError, "no such file to load -- %s", filename); }