k5_json_tid k5_json_get_tid(k5_json_value val) { json_type isa = get_isa(val); return isa->tid; }
static void disassemble_cache_client(void * x) { DisassembleCmdArgs * args = (DisassembleCmdArgs *)x; int error = 0; Context * ctx = NULL; uint8_t * mem_buf = NULL; ContextAddress buf_addr = 0; ContextAddress buf_size = 0; size_t mem_size = 0; ByteArrayOutputStream buf; OutputStream * buf_out = create_byte_array_output_stream(&buf); Channel * c = cache_channel(); char * data = NULL; size_t size = 0; ContextISA isa; memset(&isa, 0, sizeof(isa)); ctx = id2ctx(args->id); if (ctx == NULL) error = ERR_INV_CONTEXT; else if (ctx->exited) error = ERR_ALREADY_EXITED; if (!error) check_all_stopped(ctx); if (!error) { ContextAddress sym_addr = 0; ContextAddress sym_size = 0; int sym_addr_ok = 0; int sym_size_ok = 0; #if SERVICE_Symbols { Symbol * sym = NULL; if (find_symbol_by_addr(ctx, STACK_NO_FRAME, args->addr, &sym) == 0) { if (get_symbol_address(sym, &sym_addr) == 0) sym_addr_ok = 1; if (get_symbol_size(sym, &sym_size) == 0) sym_size_ok = 1; } if (sym_addr_ok && sym_addr <= args->addr) { if (args->addr - sym_addr >= 0x1000) { sym_addr_ok = 0; sym_size_ok = 0; } else if (sym_size_ok && sym_addr + sym_size > args->addr + args->size) { sym_size = args->addr + args->size - sym_addr; } } } #endif #if SERVICE_LineNumbers if (!sym_addr_ok || !sym_size_ok) { CodeArea * area = NULL; address_to_line(ctx, args->addr, args->addr + 1, address_to_line_cb, &area); if (area != NULL) { sym_addr = area->start_address; sym_size = area->end_address - area->start_address; sym_addr_ok = 1; sym_size_ok = 1; } } #endif if (sym_addr_ok && sym_size_ok && sym_addr <= args->addr && sym_addr + sym_size > args->addr) { buf_addr = sym_addr; buf_size = sym_size; mem_size = (size_t)sym_size; } else if (sym_addr_ok && sym_addr < args->addr) { if (get_isa(ctx, sym_addr, &isa) < 0) { error = errno; } else { buf_addr = sym_addr; buf_size = args->addr + args->size - sym_addr; if (isa.max_instruction_size > 0) { mem_size = (size_t)(buf_size + isa.max_instruction_size); } else { mem_size = (size_t)(buf_size + MAX_INSTRUCTION_SIZE); } } } else { /* Use default address alignment */ if (get_isa(ctx, args->addr, &isa) < 0) { error = errno; } else { if (isa.alignment > 0) { buf_addr = args->addr & ~(ContextAddress)(isa.alignment - 1); } else { buf_addr = args->addr & ~(ContextAddress)(DEFAULT_ALIGMENT - 1); } buf_size = args->addr + args->size - buf_addr; if (isa.max_instruction_size > 0) { mem_size = (size_t)(buf_size + isa.max_instruction_size); } else { mem_size = (size_t)(buf_size + MAX_INSTRUCTION_SIZE); } } } if (!error) { mem_buf = (uint8_t *)tmp_alloc(mem_size); if (context_read_mem(ctx, buf_addr, mem_buf, mem_size) < 0) error = errno; if (error) { #if ENABLE_ExtendedMemoryErrorReports MemoryErrorInfo info; if (context_get_mem_error_info(&info) == 0 && info.size_valid > 0) { mem_size = info.size_valid; error = 0; } #endif } } } if (!error && disassemble_block( ctx, buf_out, mem_buf, buf_addr, buf_size, mem_size, &isa, args) < 0) error = errno; if (get_error_code(error) == ERR_CACHE_MISS) { loc_free(buf.mem); buf.mem = NULL; buf.max = 0; buf.pos = 0; } cache_exit(); get_byte_array_output_stream_data(&buf, &data, &size); if (!is_channel_closed(c)) { OutputStream * out = &c->out; write_stringz(out, "R"); write_stringz(out, args->token); write_errno(out, error); if (size > 0) { write_block_stream(out, data, size); } else { write_string(out, "null"); } write_stream(out, 0); write_stream(out, MARKER_EOM); } loc_free(data); }
/** Update prior to unparsing */ bool SgAsmElfFileHeader::reallocate() { /* Reallocate superclass. This also calls reallocate() for all the sections associated with this ELF File Header. */ bool reallocated = SgAsmGenericHeader::reallocate(); /* Resize header based on current word size */ rose_addr_t need; if (4==get_word_size()) { need = sizeof(Elf32FileHeader_disk); } else if (8==get_word_size()) { need = sizeof(Elf64FileHeader_disk); } else { throw FormatError("unsupported ELF word size"); } if (need < get_size()) { if (is_mapped()) { ROSE_ASSERT(get_mapped_size()==get_size()); set_mapped_size(need); } set_size(need); reallocated = true; } else if (need > get_size()) { get_file()->shift_extend(this, 0, need-get_size(), SgAsmGenericFile::ADDRSP_ALL, SgAsmGenericFile::ELASTIC_HOLE); reallocated = true; } /* Update ELF-specific file class data member from generic data. */ switch(get_word_size()) { case 4: p_e_ident_file_class = 1; break; case 8: p_e_ident_file_class = 2; break; default: ROSE_ASSERT(!"invalid word size"); break; } /* Byte order. According to the spec, valid values are 1 (little-endian) and 2 (big-endian). However, we've seen cases * where a value of zero is used to indicate "native" order (loader assumes words are in the order of the machine on which * the loader is running, and the ROSE ELF parser determines the order by looking at other fields in the header). Any * original value other than 1 or 2 will be written to the new output; otherwise we choose 1 or 2 based on the currently * defined byte order. */ if (p_e_ident_data_encoding==1 || p_e_ident_data_encoding==2) { p_e_ident_data_encoding = ByteOrder::ORDER_LSB==get_sex() ? 1 : 2; } /* Update ELF-specific file type from generic data. */ switch (p_exec_format->get_purpose()) { case PURPOSE_UNSPECIFIED: case PURPOSE_PROC_SPECIFIC: case PURPOSE_OS_SPECIFIC: case PURPOSE_OTHER: /* keep as is */ break; case PURPOSE_LIBRARY: if (p_e_type==1 || p_e_type==3) { /* keep as is */ } else { p_e_type = 1; } break; case PURPOSE_EXECUTABLE: p_e_type = 2; break; case PURPOSE_CORE_DUMP: p_e_type = 4; } /* Update ELF machine type. */ p_e_machine = isa_to_machine(get_isa()); /* The ELF header stores its own size */ p_e_ehsize = get_size(); return reallocated; }
static int disassemble_block(Context * ctx, OutputStream * out, uint8_t * mem_buf, ContextAddress buf_addr, ContextAddress buf_size, ContextAddress mem_size, ContextISA * isa, DisassembleCmdArgs * args) { ContextAddress offs = 0; Disassembler * disassembler = NULL; Context * cpu = context_get_group(ctx, CONTEXT_GROUP_CPU); int disassembler_ok = 0; DisassemblerParams param; param.ctx = ctx; param.big_endian = ctx->big_endian; param.pseudo_instr = args->pseudo_instr; param.simplified = args->simplified; if (args->isa) { isa->isa = args->isa; isa->addr = args->addr; isa->size = args->size; } write_stream(out, '['); while (offs < buf_size && offs < mem_size) { ContextAddress addr = buf_addr + offs; ContextAddress size = mem_size - offs; DisassemblyResult * dr = NULL; if (args->isa == NULL && (addr < isa->addr || (isa->addr + isa->size >= isa->addr && addr >= isa->addr + isa->size))) { if (get_isa(ctx, addr, isa) < 0) return -1; disassembler_ok = 0; } if (!disassembler_ok) { disassembler = find_disassembler(cpu, isa->isa); if (disassembler == NULL) disassembler = find_disassembler(cpu, isa->def); disassembler_ok = 1; } if (disassembler) dr = disassembler(mem_buf + (size_t)offs, addr, size, ¶m); if (dr == NULL) { static char buf[32]; static DisassemblyResult dd; memset(&dd, 0, sizeof(dd)); if (isa->alignment >= 4 && (addr & 0x3) == 0 && offs <= mem_size + 4) { unsigned i; uint32_t v = 0; for (i = 0; i < 4; i++) v |= (uint32_t)mem_buf[offs + i] << (i * 8); snprintf(buf, sizeof(buf), ".word 0x%08x", v); dd.size = 4; } else if (isa->alignment >= 2 && (addr & 0x1) == 0 && offs <= mem_size + 2) { unsigned i; uint16_t v = 0; for (i = 0; i < 2; i++) v |= (uint16_t)mem_buf[offs + i] << (i * 8); snprintf(buf, sizeof(buf), ".half 0x%04x", v); dd.size = 2; } else { snprintf(buf, sizeof(buf), ".byte 0x%02x", mem_buf[offs]); dd.size = 1; } dd.text = buf; dr = ⅆ } assert(dr->size > 0); if (offs > 0) write_stream(out, ','); write_stream(out, '{'); json_write_string(out, "Address"); write_stream(out, ':'); json_write_uint64(out, addr); write_stream(out, ','); json_write_string(out, "Size"); write_stream(out, ':'); json_write_uint64(out, dr->size); write_stream(out, ','); json_write_string(out, "Instruction"); write_stream(out, ':'); write_stream(out, '['); write_stream(out, '{'); json_write_string(out, "Type"); write_stream(out, ':'); json_write_string(out, "String"); write_stream(out, ','); json_write_string(out, "Text"); write_stream(out, ':'); json_write_string(out, dr->text); write_stream(out, '}'); write_stream(out, ']'); if (args->opcode_value) { write_stream(out, ','); json_write_string(out, "OpcodeValue"); write_stream(out, ':'); json_write_binary(out, mem_buf + (size_t)offs, (size_t)dr->size); } write_stream(out, '}'); offs += dr->size; } write_stream(out, ']'); return 0; }