Beispiel #1
0
k5_json_tid
k5_json_get_tid(k5_json_value val)
{
    json_type isa = get_isa(val);

    return isa->tid;
}
Beispiel #2
0
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);
}
Beispiel #3
0
/** 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;
}
Beispiel #4
0
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, &param);
        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 = &dd;
        }
        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;
}