2017-09-21 23 views
1

Power8로 PowerPC에서 실행할 때 endianess 문제를 추적하려고합니다. 빅 엔디안은 괜찮습니다. 리틀 엔디안은 문제가 있습니다.벡터 변수를 128 비트 vsx 값으로 인쇄하는 방법은 무엇입니까?

이하 uint8x16_p8__vector unsigned char에 대해 typedef입니다. 큰 엔디안 시스템에서 I는 다음을 참조하십시오

1110  uint8x16_p8 r5 = (uint8x16_p8)VectorLoadKey(s_mask); 
(gdb) 
1112  for (unsigned int i=0; i<rounds-2; ++i) 
(gdb) p r5 
$1 = {0xd, 0xe, 0xf, 0xc, 0xd, 0xe, 0xf, 0xc, 0xd, 0xe, 0xf, 0xc, 0xd, 0xe, 
    0xf, 0xc} 

을 내가 볼 조금 엔디안 시스템에서 :

1110  uint8x16_p8 r5 = (uint8x16_p8)VectorLoadKey(s_mask); 
(gdb) 
1112  for (unsigned int i=0; i<rounds-2; ++i) 
(gdb) p r5 
$1 = {0xc, 0xf, 0xe, 0xd, 0xc, 0xf, 0xe, 0xd, 0xc, 0xf, 0xe, 0xd, 0xc, 0xf, 
    0xe, 0xd} 

GDB는 메모리 레이아웃 사용되는 값을 인쇄 할 때 :

(gdb) ptype r5 
type = unsigned char __attribute__ ((vector_size(16))) 
(gdb) 

I을 vsx 레지스터에로드 될 때 128 비트 정수 값을보고 싶습니다. vsx 레지스터 값은 중요한 값이며, 항상 빅 엔디안입니다. vsx 값에 차이가 있으면 메모리에서로드하는 동안 벡터를 바꿔야한다는 것을 알고 있습니다. 또한

, GDB는 uint128_t를 지원하기 위해 표시되지 않습니다 :

(gdb) p *(uint128_t)r5 
No symbol "uint128_t" in current context. 

어떻게 GDB는 VSX 레지스터 값 (그리고 메모리 레이아웃 값)을 인쇄해야합니까?


GDB의 또 다른 문제점은 "여기"라는 형식을 분해 할 수 없기 때문에 레지스터를 인쇄 할 위치를 찾을 수 없다는 것입니다. 예를 들어, disass .은 (는 구문 오류가 발생합니다) "여기에서 분해"하지 않는다, 나는 (이 함수의 시작처럼 보인다)하고 어디 $pc를 사용하여 분해하지 않습니다

(gdb) disass $pc 
Dump of assembler code for function Rijndael_UncheckedSetKey_POWER8(...): 
    0x00000000104b82c8 <+0>:  lis  r2,4213 
    0x00000000104b82cc <+4>:  addi r2,r2,-29952 
    0x00000000104b82d0 <+8>:  mflr r0 
    0x00000000104b82d4 <+12>: std  r0,16(r1) 
    0x00000000104b82d8 <+16>: std  r31,-8(r1) 
    0x00000000104b82dc <+20>: stdu r1,-272(r1) 
    0x00000000104b82e0 <+24>: mr  r31,r1 
    0x00000000104b82e4 <+28>: std  r3,208(r31) 
    0x00000000104b82e8 <+32>: std  r4,216(r31) 
    0x00000000104b82ec <+36>: std  r5,224(r31) 
    0x00000000104b82f0 <+40>: std  r6,232(r31) 
    0x00000000104b82f4 <+44>: mr  r9,r7 
    0x00000000104b82f8 <+48>: stw  r9,240(r31) 
    0x00000000104b82fc <+52>: ld  r9,216(r31) 
    0x00000000104b8300 <+56>: cmpdi cr7,r9,16 
    0x00000000104b8304 <+60>: bne  cr7,0x104b8548 <Rijndael_UncheckedSetKey_POWER8(...)+640> 
    0x00000000104b8308 <+64>: ld  r9,208(r31) 
    0x00000000104b830c <+68>: std  r9,32(r31) 
---Type <return> to continue, or q <return> to quit--- 
... 

답변

1

__int128_t을 시도,

[[email protected] ~]$ gdb -quiet ./test 
Reading symbols from ./test...done. 
(gdb) break test.c:12 
Breakpoint 1 at 0x100005ec: file test.c, line 12. 
(gdb) run 
Starting program: /home/jk/test 

Breakpoint 1, main() at test.c:12 
12  return 0; 
(gdb) print s 
$1 = 0x00000003000000020000000100000000 
(gdb) 
: 다음

#include <stdint.h> 

int main(void) 
{ 
    __uint128_t s; 
    vector int v = { 0, 1, 2, 3 }; 

    s = (__uint128_t)v; 

    (void)s; 

    return 0; 
} 

, 당신은 정상 값으로 당신의 __uint128_t 스칼라를 인쇄 할 수 있어야한다 : 이는 GCC에 의해 & GDB를 지원 스칼라에 캐스팅 레지스터 값에 영향을 미칠 수 있음을 명심 그러나

(gdb) p $vs0 
$5 = {uint128 = 0x00000003000000020000000100000000, v2_double = { 
    2.1219957909652723e-314, 6.3659873738839482e-314}, v4_float = {0, 
    1.40129846e-45, 2.80259693e-45, 4.20389539e-45}, v4_int32 = {0, 1, 2, 3}, 
    v8_int16 = {0, 0, 1, 0, 2, 0, 3, 0}, v16_int8 = {0, 0, 0, 0, 1, 0, 0, 0, 2, 
    0, 0, 0, 3, 0, 0, 0}} 

; 당신이 사용 등록을 알고있는 경우 0

또는, 단지 $<reg> 표기법을 사용하여, 직접 레지스터 값을 출력 확실하지 않으면 해체를 확인하십시오.

+0

감사합니다. Jeremy. 리틀 엔디안 리눅스 시스템 인 GCC112에서 작동하는 것으로 보입니다. 불행히도 빅 엔디안 AIX 머신 인 GCC119에서는 작동하지 않습니다. GCC119가 * "오류 : '__uint128_t'이 (가)이 범위에서 선언되지 않았습니다 '라는 오류가 발생합니다. *. 그러나 앞으로 나아갈 수있을 것입니다. – jww