static void print_method(compile_t* c, printbuf_t* buf, reachable_type_t* t, const char* name, ast_t* typeargs) { const char* funname = genname_fun(t->name, name, typeargs); LLVMValueRef func = LLVMGetNamedFunction(c->module, funname); if(func == NULL) return; // Get a reified function. ast_t* fun = get_fun(t->ast, name, typeargs); if(fun == NULL) return; AST_GET_CHILDREN(fun, cap, id, typeparams, params, rtype, can_error, body, docstring); // Print the docstring if we have one. if(ast_id(docstring) == TK_STRING) { printbuf(buf, "/*\n" "%s" "*/\n", ast_name(docstring) ); } // Print the function signature. print_type_name(c, buf, rtype); printbuf(buf, " %s", funname); switch(ast_id(fun)) { case TK_NEW: case TK_BE: { ast_t* def = (ast_t*)ast_data(t->ast); if(ast_id(def) == TK_ACTOR) printbuf(buf, "__send"); break; } default: {} } printbuf(buf, "("); print_type_name(c, buf, t->ast); printbuf(buf, " self"); print_params(c, buf, params); printbuf(buf, ");\n\n"); ast_free_unattached(fun); }
static void print_method(compile_t* c, printbuf_t* buf, reach_type_t* t, reach_method_t* m) { if(!emit_fun(m->r_fun)) return; AST_GET_CHILDREN(m->r_fun, cap, id, typeparams, params, rtype, can_error, body, docstring); // Print the docstring if we have one. if(ast_id(docstring) == TK_STRING) { printbuf(buf, "/*\n" "%s" "*/\n", ast_name(docstring) ); } // Print the function signature. if((ast_id(cap) != TK_AT) || !is_none(rtype)) print_type_name(c, buf, rtype); else printbuf(buf, "void"); printbuf(buf, " %s", m->full_name); switch(ast_id(m->r_fun)) { case TK_NEW: case TK_BE: { ast_t* def = (ast_t*)ast_data(t->ast); if(ast_id(def) == TK_ACTOR) printbuf(buf, "__send"); break; } default: {} } printbuf(buf, "("); if(ast_id(cap) != TK_AT) { print_type_name(c, buf, t->ast); printbuf(buf, " self"); print_params(c, buf, params, true); } else { print_params(c, buf, params, false); } printbuf(buf, ");\n\n"); }
static void print_params(compile_t* c, printbuf_t* buf, ast_t* params) { ast_t* param = ast_child(params); while(param != NULL) { AST_GET_CHILDREN(param, id, ptype); // Print the parameter. printbuf(buf, ", "); print_type_name(c, buf, ptype); // Smash trailing primes to underscores. const char* name = ast_name(id); size_t len = strlen(name) + 1; size_t buf_size = len; char* buffer = (char*)ponyint_pool_alloc_size(buf_size); memcpy(buffer, name, len); len--; while(buffer[--len] == '\'') buffer[len] = '_'; printbuf(buf, " %s", buffer); param = ast_sibling(param); ponyint_pool_free_size(buf_size, buffer); } }
/* * Display a disassembled instruction with annotation */ static void print_one_insn(struct ca_dis_insn* insn, struct ui_out* uiout) { int i, pos; struct ca_operand* dst_op; ui_out_text(uiout, insn->dis_string); pos = strlen(insn->dis_string); if (pos < MAX_SPACING) ui_out_spaces(uiout, MAX_SPACING - pos); ui_out_text(uiout, " ## "); if (insn->num_operand == 0) { ui_out_text(uiout, "\n"); return; } // special case /*if (insn->call) { // reminder that $rax is set to return value after a "call" instruction // if the called function has an integer return value // (unfortunately return type is not known for a function) ui_out_text(uiout, "(%rax=? on return) "); }*/ dst_op = &insn->operands[0]; // annotation of object context if (insn->annotate) { size_t ptr_sz = g_ptr_bit >> 3; int has_value = 0; size_t val = 0xcdcdcdcd; int op_size = insn->op_size; const char* symname = NULL; struct win_type type = {0,0}; int is_vptr = 0; char* name_to_free = NULL; // update register context by "pc" set_current_reg_pointers(insn); // Get the instruction's destination value/symbol/type if (dst_op->type == CA_OP_MEMORY) { // if the destination is a known local variable if (is_stack_address(dst_op)) { address_t addr = get_address(dst_op); struct ca_stack_var* sval = get_stack_var(addr); if (sval) { symname = sval->sym_name; type = sval->type; } else { /*struct symbol* sym; struct object_reference aref; memset(&aref, 0, sizeof(aref)); aref.vaddr = addr; aref.value = 0; aref.target_index = -1; sym = get_stack_sym(&aref, NULL, NULL); if (sym) { symname = SYMBOL_PRINT_NAME (sym); type = SYMBOL_TYPE(sym); }*/ get_stack_sym_and_type(addr, &symname, &type); } } // could it be a known heap object if (!symname && !type.mod_base) { // this function will allocate buffer for the symbol name if any, remember to free it get_op_symbol_type(dst_op, 0, &name_to_free, &type, NULL); symname = name_to_free; } // Since flag insn->annotate is set, dst_op's value should be calculated val = get_op_value(dst_op, op_size); has_value = 1; } else if (dst_op->type == CA_OP_REGISTER) { struct ca_reg_value* dst_reg = get_reg_at_pc(dst_op->reg.index, insn->pc); if (dst_reg) { symname = dst_reg->sym_name; type = dst_reg->type; is_vptr = dst_reg->vptr; if (dst_reg->has_value) { has_value = 1; val = dst_reg->value; } } } else if (dst_op->type == CA_OP_IMMEDIATE) { val = get_op_value(dst_op, op_size); has_value = 1; } if (dst_op->type != CA_OP_IMMEDIATE) { // Name and value (if known) of destination print_one_operand(uiout, dst_op, op_size); if (has_value) ui_out_message(uiout, 0, "="PRINT_FORMAT_POINTER, val); else ui_out_text(uiout, "=?"); } // Symbol or type of destination if (dst_op->type == CA_OP_REGISTER && dst_op->reg.index == RSP) { if (val == g_debug_context.sp) ui_out_text(uiout, " End of function prologue"); ui_out_text(uiout, "\n"); } else { // symbol or type is known if (symname || type.mod_base) { ui_out_text(uiout, "("); if (symname) { ui_out_message(uiout, 0, "symbol=\"%s\"", symname); } if (type.mod_base) { //CHECK_TYPEDEF(type); if (symname) ui_out_text(uiout, " "); ui_out_text(uiout, "type=\""); /*if (is_vptr) { const char * type_name = type_name_no_tag(type); if (type_name) ui_out_message(uiout, 0, "vtable for %s", type_name); else { ui_out_text(uiout, "vtable for "); print_type_name (type); } } else*/ print_type_name (type); ui_out_text(uiout, "\""); } ui_out_text(uiout, ")\n"); } // whatever we can get form the value else { address_t location = 0; int offset = 0; //if (insn->num_operand > 1) //{ // struct ca_operand* src_op = &insn->operands[1]; // get_location(src_op, &location, &offset); //} print_op_value_context (val, op_size > 0 ? op_size : ptr_sz, location, offset, insn->lea); } } if (name_to_free) free (name_to_free); }
int main(int argc, char **argv) { int fd,out,i; struct stat sb; char *addr,*shptr,*string_pointer,*name; uint32_t temp; uint16_t temp16; uint32_t phoff,phnum; uint32_t shnum,shoff,shsize,strindex; uint32_t bss_size=0,data_size=0,text_size=0; uint32_t text_start=0,data_start=0,bss_start=0,bss_end=0; // uint32_t data_offset=0,text_offset=0,bss_offset=0; uint32_t entry=0,size,offset; if (argc<3) { print_usage(argv[0]); return 5; } fd=open(argv[1],O_RDONLY); if (fd<0) { printf("Error opening file %s\n",argv[1]); return 6; } out=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0777); if (out<0) { printf("Error opening file %s\n",argv[2]); return 7; } if (fstat(fd, &sb) < 0) { printf("Error with fstat\n"); return 7; } addr=mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { printf("Error mmaping!\n"); return 8; } if ((addr[0]==0x7f) && (addr[1]=='E') && (addr[2]=='L') && (addr[3]=='F')) { if (debug) printf("Found elf\n"); } else { printf("NOT AN ELF FILE!\n"); return 9; } if (debug) { printf("Size: %d bit\n",addr[4]==1?32:64); printf("Endian: %s\n",addr[5]==1?"little":"big"); printf("Version %d\n",addr[6]); printf("ABI %d\n",addr[7]); printf("Type %d:%d\n",addr[0x10],addr[0x11]); printf("ISA %d:%d (40==ARM)\n",addr[0x12],addr[0x13]); memcpy(&temp,&addr[0x14],4); printf("Version again %d\n",temp); } memcpy(&temp,&addr[0x18],4); entry=temp; if (debug) printf("Entry %x\n",temp); memcpy(&temp,&addr[0x1c],4); phoff=temp; if (debug) printf("Phoff %x\n",phoff); memcpy(&temp,&addr[0x20],4); shoff=temp; if (debug) printf("Shoff %x\n",temp); if (debug) { memcpy(&temp,&addr[0x24],4); printf("Flags %x\n",temp); memcpy(&temp16,&addr[0x28],2); printf("ehsize %x\n",temp16); memcpy(&temp16,&addr[0x2a],2); printf("phentsize %x\n",temp16); } memcpy(&temp16,&addr[0x2c],2); phnum=temp16; if (debug) printf("phnum %x\n",temp16); memcpy(&temp16,&addr[0x2e],2); shsize=temp16; if (debug) printf("shentsize %x\n",temp16); memcpy(&temp16,&addr[0x30],2); shnum=temp16; if (debug) printf("shnum %x\n",temp16); memcpy(&temp16,&addr[0x32],2); strindex=temp16; if (debug) printf("shstrndx %x\n",temp16); if (debug) { printf("%d ph entries starting at %x\n",phnum,phoff); printf("%d sh entries starting at %x, size %d\n", shnum,shoff,shsize); } shptr=&addr[shoff]; /* get string pointer */ string_pointer=&shptr[strindex*shsize]; memcpy(&temp,&string_pointer[0x10],4); string_pointer=&addr[temp]; /* get sizes */ for(i=0;i<shnum;i++) { memcpy(&temp,&shptr[0x4],4); if (debug) { printf("\ttype: "); print_type_name(temp); printf("\n"); } if (temp==SHT_PROGBITS) { if (debug) printf("Section header %d\n",i); memcpy(&temp,&shptr[0x0],4); name=string_pointer+temp; /* Don't write out comment */ if (!strcmp(name,".comment")) { } else if (!strncmp(name,".text",6)) { memcpy(&temp,&shptr[0x10],4); offset=temp; memcpy(&temp,&shptr[0x14],4); text_size=temp; if (debug) { printf("\ttext_start: %x\n",text_start); printf("\ttext_size: %x\n",text_size); } } else if (!strncmp(name,".rodata",6)) { memcpy(&temp,&shptr[0x10],4); offset=temp; memcpy(&temp,&shptr[0x14],4); text_size=(offset-entry)+temp; if (debug) { printf("\trodata_start: %x\n",offset); printf("\ttext_size: %x\n",text_size); } } else if (!strncmp(name,".data",5)) { memcpy(&temp,&shptr[0x10],4); offset=temp; memcpy(&temp,&shptr[0x14],4); data_size=temp; data_start=offset-entry; if (debug) { printf("\tdata_start: %x, %x %d\n", data_start,offset,data_size); } } else { //printf("What to do with %s\n",name); } } /* Handle bss */ if (temp==SHT_NOBITS) { if (debug) printf("Section header %d\n",i); memcpy(&temp,&shptr[0x0],4); name=string_pointer+temp; /* Don't write out comment */ if (!strncmp(name,".bss",4)) { memcpy(&temp,&shptr[0x0c],4); offset=temp; bss_start=offset-entry; memcpy(&temp,&shptr[0x14],4); bss_size=temp; if (debug) printf("\tbss_start,size: %x %d\n", bss_start,bss_size); } else { printf("bss: what to do with %s\n",name); } } shptr+=shsize; } /***************************/ /* Write out the bflt file */ /***************************/ text_start=0x40; if (data_start==0) { data_start=text_start+text_size; } else { data_start+=text_start; } if (bss_start==0) { bss_start=data_start+data_size; bss_end=data_start+data_size; } else { bss_start+=text_start; bss_end=bss_start+bss_size; } /* magic */ write(out,"bFLT",4); /* version. We're version 4 for now */ temp=htonl(4); write(out,&temp,4); /* entry. Entry after end of header */ if (debug) printf("BFLT: text_start %x\n",text_start); temp=htonl(text_start); write(out,&temp,4); /* data_start */ if (debug) printf("BFLT: data_start %x\n",data_start); temp=htonl(data_start); write(out,&temp,4); /* data_end */ if (debug) printf("BFLT: data_end %x\n",bss_start); temp=htonl(bss_start); write(out,&temp,4); /* bss_end */ if (debug) printf("BFLT: bss_end %x\n",bss_end); temp=htonl(bss_end); write(out,&temp,4); /* stack size */ temp=htonl(8192); write(out,&temp,4); /* reloc start */ temp=0; write(out,&temp,4); /* reloc count */ temp=0; write(out,&temp,4); /* flags */ temp=0; write(out,&temp,4); /* padding */ for(i=0;i<6;i++) { write(out,&temp,4); } /* write out data */ shptr=&addr[shoff]; if (debug) printf("Writing data:\n"); for(i=0;i<shnum;i++) { memcpy(&temp,&shptr[0x4],4); if (temp==SHT_PROGBITS) { if (debug) printf("Section header %d\n",i); memcpy(&temp,&shptr[0x0],4); name=string_pointer+temp; /* Don't write out comment */ if (!strcmp(name,".comment")) { } else if ((!strncmp(name,".text",5)) || (!strncmp(name,".rodata",6))) { if (debug) printf("Writing text: %s!\n",name); memcpy(&temp,&shptr[0x10],4); offset=temp; if (debug) printf("\toffset: %x\n",offset); memcpy(&temp,&shptr[0x14],4); size=temp; if (debug) printf("\tsize: %x\n",size); if (debug) printf("Seeking to %x\n", text_start+offset-entry); lseek(out,text_start+offset-entry,SEEK_SET); write(out,&addr[offset],size); } else if (!strncmp(name,".data",5)) { if (debug) printf("Writing data: %s\n",name); memcpy(&temp,&shptr[0x10],4); offset=temp; if (debug) printf("\toffset: %x\n",offset); memcpy(&temp,&shptr[0x14],4); size=temp; if (debug) printf("\tsize: %x\n",size); if (debug) printf("Seeking to %x\n", text_start+offset-entry); lseek(out,text_start+offset-entry,SEEK_SET); write(out,&addr[offset],size); } else { printf("What to do with %s\n",name); return -1; } } shptr+=shsize; } munmap(addr, sb.st_size); close(fd); close(out); return 0; }
// print some general information about the image: type name, // dimensions. vint8 general_image::print_header() const { print_type_name(type_name); function_print(", %li channels, %li rows, %li cols\n", bands, rows, cols); return 1; }