Can openocd read call stack and local variable correct?

//debug source section

static void pl2303_gpio_set(struct gpio_chip *chip, unsigned offset, int value)

{

struct pl2303_gpio *gpio = to_pl2303_gpio(chip);

struct pl2303_gpio_desc *desc;

mutex_lock(&gpio->lock);

desc = gpio->descs + offset;

if (value) //—>break here

gpio->data[desc->value_offset] |= desc->value_mask;

else

gpio->data[desc->value_offset] &= ~desc->value_mask;

pl2303_vendor_write(desc->value_ctrl, gpio->data[desc->value_offset], gpio->serial);

mutex_unlock(&gpio->lock);

}

////////////////////////////////////////openocd

/root/project_board/free_imx/myandroid/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-gdb

(gdb) target remote localhost:3333

(gdb) symbol-file /root/project_board/free_imx/out/matrix_io/kernel/vmlinux

(gdb) mon halt

(gdb) break /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c:297

(gdb) continue

Breakpoint 1, pl2303_gpio_set (chip=0x800719bc, offset=3159793204, value=-2114730436)

at /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c:297

297 if (value)

(gdb) p value

$7 = -2114730436

Breakpoint 1, pl2303_vendor_write (value=65535, index=65535, serial=0x0)

at /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c:218

218 return res;

(gdb) p &index

$1 = (__u16 *) 0xbccb9d9c

(gdb) p &value

$2 = (__u16 *) 0xbccb9d9e

(gdb) p &res

$3 = (int *) 0xbccb9dac

https://picasaweb.google.com/1061855410 … 8164287378

////////////////////////////////////////

//////////////////////////////////////KGDB

(gdb) target remote /dev/ttyUSB0

Remote debugging using /dev/ttyUSB0

kgdb_breakpoint ()

at /root/project_board/free_imx/myandroid/kernel_imx/kernel/debug/debug_core.c:1025

1025 arch_kgdb_breakpoint();

(gdb) break /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c:297

Breakpoint 1 at 0x8075bfd0: file /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c, line 297.

(gdb) continue

Continuing.

Breakpoint 1, pl2303_gpio_set (chip=0xbc5e99e4, offset=0, value=0)

at /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c:297

(gdb) p value

$1 = 0

Breakpoint 1, pl2303_vendor_write (value=1, index=48, serial=0xbc5d7980)

at /root/project_board/free_imx/myandroid/kernel_imx/drivers/usb/serial/pl2303.c:218

218 return res;

(gdb) p &index

$10 = (__u16 *) 0xbccb9d9c

(gdb) p &value

$11 = (__u16 *) 0xbccb9d9e

(gdb) p &res

$12 = (int *) 0xbccb9dac

https://picasaweb.google.com/1061855410 … 7029124338

/////////////////////////////////////////////////////////////////////////

value = 0 is correct on kgdb

openocd and kgdb symbol address are the same

openocd global variable is good, only local variable is wrong. can fixed it?

and call stack jsut can see 2 or 3 layer.

kgdb can read all struct variable and call stacks

can make openocd like kgdb?

bug similar as this but not sure~~~how to fix openocd

https://code.google.com/p/go/issues/detail?id=8256

here is a way debug openocd with eclipse

https://picasaweb.google.com/1061855410 … 8760449330

c/c++ application: /root/openocd-0.9.0/src/openocd

arguments: -f /opt/openocd/share/openocd/scripts/interface/ftdi/dp_busblaster.cfg -f /opt/openocd/share/openocd/scripts/target/imx6.cfg

i compare global and local variable in openocd

static int gdb_read_memory_packet(struct connection *connection, char const *packet, int packet_size)

into cortex_a_read_phys_memory

get value is wrong on local variable

any idea for me?

I write local variable 0x03, address=0x4ccd7d86, buffer={0x03, 0x00}

retval = cortex_a_write_phys_memory(target, address, size, count, buffer);

then Read local variable, address= 0x4ccd7d86

retval = cortex_a_read_phys_memory(target, address, size, count, buffer);

buffer = {0x03,0x00}

the value is 0x03 is ok~~~

get local variable still wrong

static int cortex_a_read_memory(struct target *target,

uint32_t address,

uint32_t size,

uint32_t count,

uint8_t *buffer)

{

int mmu_enabled = 0;

//uint32_t virt, phys;

int retval;

struct armv7a_common* armv7a = target_to_armv7a(target);

//struct adiv5_dap* swjdp = armv7a->arm.dap;

//uint8_t apsel = swjdp->apsel;

/* cortex_a handles unaligned memory access */

LOG_DEBUG(“Reading memory at address 0x%” PRIx32 “; size %” PRId32 “; count %” PRId32, address, size, count);

/* determine if MMU was enabled on target stop */

if (!armv7a->is_armv7r)

{

retval = cortex_a_mmu(target, &mmu_enabled);

if (retval != ERROR_OK)

return retval;

}

/////when I mark this section the local pointer variable is correct, but local variable is wrong too

////

////

/*if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap))

{

if (mmu_enabled)

{

virt = address;

retval = cortex_a_virt2phys(target, virt, &phys);

if (retval != ERROR_OK)

return retval;

LOG_DEBUG(“Reading at virtual address. Translating v:0x%” PRIx32 " to r:0x%" PRIx32, virt, phys);

address = phys;

}

retval = cortex_a_read_phys_memory(target, address, size, count, buffer);

}

else*/

{

if (mmu_enabled)

{

retval = cortex_a_check_address(target, address);

if (retval != ERROR_OK)

return retval;

/* enable MMU as we could have disabled it for phys access */

retval = cortex_a_mmu_modify(target, 1);

if (retval != ERROR_OK)

return retval;

}

retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);

}

return retval;

}

/root/openocd-0.9.0/src/target/cortex_a.c

modify

armv7a->memory_ap_available = true;

to

armv7a->memory_ap_available = false;

watch local variable of address value is correct… still have local variable wrong

use Advanced Highperformance Bus can not read local address value

but use Advanced Peripheral Bus can read local address value

Fixed~~~~~~~~~~~~~~~~

use APB read/write memory

if one time fast read, first 4 bytes are correct, but others are wrong

use slow path read can fix it

demo photo:

  1. https://picasaweb.google.com/1061855410 … 1048247058

  2. https://picasaweb.google.com/1061855410 … 9468163938

  3. https://picasaweb.google.com/1061855410 … 4608161106

Detail:

http://fatalfeel.blogspot.tw/2015/12/op … el-of.html

//////////////////////////

gedit /root/openocd-0.9.0/src/target/target.c

static int target_read_buffer_default(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer)

{

int retval;

int remain;

unsigned int one_unit;

unsigned int length;

unsigned int ptr_shift;

retval = -1;

ptr_shift = 0;

remain = count;

if( address > 0 )

{

while( remain > 0 )

{

if( remain >= (int)sizeof(uint32_t) )

{

one_unit = sizeof(uint32_t);

length = remain/sizeof(uint32_t);

}

else if( remain >= (int)sizeof(uint16_t) )

{

one_unit = sizeof(uint16_t);

length = remain/sizeof(uint16_t);

}

else

{

one_unit = sizeof(uint8_t);

length = remain/sizeof(uint8_t);

}

retval = target_read_memory(target, address+ptr_shift, one_unit, length, buffer+ptr_shift);

if (retval != ERROR_OK)

break;

ptr_shift += one_unit * length;

remain -= one_unit * length;

} //end while

}

return retval;

}

////////

in static int cortex_a_examine_first(struct target *target)

retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7a->memory_ap);

//modify to

retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv7a->memory_ap);

////////

//Use slow path

gedit /root/openocd-0.9.0/src/target/cortex_a.c

//in cortex_a_read_apb_ab_memory

if (size == 4 && (address % 4) == 0)

//change to

if( 0 )

http://arttools.blogspot.tw/2009/09/deb … ystem.html

For configuring systems at start up, such as setting memory controller parameters, clocks and PLL registers, memory access through the AHB access port is good. This should also work well for writing to flash memories.

For debugging code running on the MPU, the APB and access through the MPU core probably should be used, since this method avoids problems with virtual to physical address translations and also helps avoid cache coherency problems.

in armv7a.c

struct armv7a_common *armv7a = target_to_armv7a(target);

struct arm *arm = &armv7a->arm;

if (armv7a->common_magic != ARMV7_COMMON_MAGIC) {

LOG_ERROR(“BUG: called for a non-ARMv7A target”);

return ERROR_COMMAND_SYNTAX_ERROR;

}

arm_arch_state(target);

if (armv7a->is_armv7r) {

LOG_USER(“D-Cache: %s, I-Cache: %s”,

state[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled],

state[armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled]);

} else {

LOG_USER(“MMU: %s, D-Cache: %s, I-Cache: %s”,

state[armv7a->armv7a_mmu.mmu_enabled],

state[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled],

state[armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled]);

}

we can do the auto judgement for cortex_a_examine_first(struct target *target)

I prefer this way than dap apsel in cfg

because u need change dap apsel 0 or dap apsel 1

in static int cortex_a_post_debug_entry(struct target *target)

after

cortex_a->curr_mode = armv7a->arm.core_mode;

add

armv7a->memory_ap = armv7a->armv7a_mmu.mmu_enabled;

will auto select right bus~

when mmu_enabled On is debug linux kernel core

when mmu_enabled Off is debug uboot code upload on Hardware pin boot Mode0

openocd debug linux kernel on i.mx6

https://www.youtube.com/watch?v=8K1qY3St06k

openocd debug u-boot on i.mx6

https://www.youtube.com/watch?v=2L1vr_LA8Nc

http://fatalfeel.blogspot.tw/2015/12/op … el-of.html