2017-05-04 3 views
0

나는 R2K 객체 모듈에 쓰기 작업을 해왔고, 심볼 테이블 엔트리를 파일에 쓰는데 어려움을 겪고있다. 나는 memcpy를 사용하여 sym_table에 저장된 심볼 테이블의 항목을 bytes_sym이라는 1 바이트 정수로 배열 한 다음 파일에 씁니다. 올바른 크기를 복사하지만 어떤 이유로 바이트 배치가 뒤죽박죽입니다. 쓰기 전에 바이트 값은memcpy는 구조체의 내용을 뒤섞는가?

/* 
** symbol table entry 
*/  
typedef 
struct syment { 
    uint32_t flags;  /* flag word */ 
    uint32_t value;  /* value associated with this symbol */ 
    uint32_t sym;  /* symbol name's index into string table */ 
} 
    syment_t; 

// header->data[8] is the number of symbol table entries 
int sym_length = header->data[8] * sizeof(syment_t); 

uint8_t bytes_sym[sym_length]; 

for(int i = 0; i < header->data[8]; i++){ 
    memcpy(&bytes_sym[i * sizeof(syment_t)], &sym_table[i], sizeof(syment_t)); 
} 
fwrite(bytes_sym, sym_length, 1, file); 

// prints the newly copied symbol table section one byte at a time 
// I know it's gross to look at, but it's only for testing :p 
printf("New Symtab:\n"); 
for(int i = 0; i < sym_length; i++){ 
    printf("0x%x ", bytes_sym[i]); 
} 
printf("\n"); 

:

0x0 0x0 0x0 0xb1 0x0 0x40 0x0 0x2c 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0xa3 0x10 0x0 0x0 0x20 0x0 0x0 0x0 0x5 
0x0 0x0 0x40 0xb1 0x0 0x40 0x0 0x38 0x0 0x0 0x0 0xb 
0x0 0x0 0x0 0xa1 0x0 0x40 0x0 0x14 0x0 0x0 0x0 0x10 
0x0 0x0 0x40 0xb1 0x0 0x40 0x0 0x0 0x0 0x0 0x0 0x15 
0x0 0x0 0x0 0x67 0x0 0x0 0x0 0x11 0x0 0x0 0x0 0x1f 
0x0 0x0 0x0 0xa2 0x10 0x0 0x0 0x0 0x0 0x0 0x0 0x19 
0x0 0x0 0x40 0xb1 0x0 0x40 0x0 0x64 0x0 0x0 0x0 0x29 

작성 후, 그들이 (다른 안, 잘못된)은 다음과 같습니다

0xb1 0x0 0x0 0x0 0x2c 0x0 0x40 0x0 0x0 0x0 0x0 0x0 
0xa3 0x0 0x0 0x0 0x20 0x0 0x0 0x10 0x5 0x0 0x0 0x0 
0xb1 0x40 0x0 0x0 0x38 0x0 0x40 0x0 0xb 0x0 0x0 0x0 
0xa1 0x0 0x0 0x0 0x14 0x0 0x40 0x0 0x10 0x0 0x0 0x0 
0xb1 0x40 0x0 0x0 0x0 0x0 0x40 0x0 0x15 0x0 0x0 0x0 
0x67 0x0 0x0 0x0 0x11 0x0 0x0 0x0 0x1f 0x0 0x0 0x0 
0xa2 0x0 0x0 0x0 0x0 0x0 0x0 0x10 0x19 0x0 0x0 0x0 
0xb1 0x40 0x0 0x0 0x64 0x0 0x40 0x0 0x29 0x0 0x0 0x0 

나는 여기에 내 코드입니다 이 문제의 원인에 대해 머리를 감쌀 수 없으므로 도움이 될 것입니다.

+1

스택 오버플로에 오신 것을 환영합니다. 곧 [About] 및 [Ask] 페이지를 읽으십시오. 데이터 구조는 어떻게 생겼습니까? 우리는 그것에 대해 알아야합니다. MCVE ([MCVE])를 만드는 방법에 대해서도 읽어보십시오. –

+1

코드 작성 및 데이터 읽기도 살펴 보시겠습니까? 또한'0x % x'을'0x % 02x'로 만듭니다. – alk

+2

빅 엔디안 대 리틀 엔디안 문제처럼 보입니다. 우리는 더 많은 정보가 필요합니다. 특히 [MCVE]가 도움이 될 것이지만,'memcpy'는 분명히 어떤 것도 혼합하지 않을 것입니다. 문제는 다른 곳에있다. –

답변

-3

좋아, 너희들은 완전히 memcpy에 대해 내 데이터를 망칠 수 없다는 거짓말을했다. 약간의 연구를 한 후, 필자는 32 비트 객체 모듈의 심볼 테이블 섹션에있는 각 4 바이트 블록의 바이트 순서를 바꾼 엔디안 (endian)이라는 것을 알아 냈습니다. 그래서 그것을 고칠 수있는 약간의 함수를 작성했습니다 :

/// Flips the bytes in each 4 byte block after the endian flip caused by memcpy 
/// @param - the array of bytes 
/// @param - the length of the array in bytes 
/// 
void flip_bytes(uint8_t byte_array[], int length){ 

    uint8_t tmp; 
    for(int i = 0; i < length; i++){ 
      if((i+1) % 4 == 0){ 

        // switch the first and last bytes 
        tmp = byte_array[i]; 
        byte_array[i] = byte_array[i-3]; 
        byte_array[i-3] = tmp; 
        // switch the middle 2 bytes 
        tmp = byte_array[i-1]; 
        byte_array[i-1] = byte_array[i-2]; 
        byte_array[i-2] = tmp; 
      } 
    } 
} 
+4

그 자체만으로도 올바르게 사용 되었기 때문에'memcpy()'는 아무 것도 망치지 않습니다. 처음에는 문제가 무엇인지 알 수있는 충분한 정보를 제공하지 못했습니다. 이 '응답'에 충분한 정보를 제공하지 않아이 기능을 사용하는 위치와 방법을 보여줍니다. '완전히 거짓말'에 대한 귀하의 주장은 잘못되었습니다. 정의되지 않은 동작을 호출하는 코드가있을 수 있습니다. [MCVE]를 제공하지 않았기 때문에 확신하기 어렵지만 엉뚱한 코딩으로 인해 비정상적인 동작이 발생합니다. 올바르게 사용될 때 (예를 들어, 메모리의 소스 영역과 타겟 영역이 겹치지 않을 수 있습니다),'memcpy()'가 작동합니다. –

+3

오해의 소지가 있으므로이 대답을 아래로 내리십시오. 'memcpy'가 엔디안을 인식하고 바이트를 다른 순서로 소스에 쓰는 것은 잘못된 것입니다. 아마도 소스 데이터 자체가 예상 한 것과 다른 엔디안을 사용한다는 것입니다. 이것은 데이터 형식 문제이며'memcpy '와는 관련이 없습니다. – paddy

+0

이 의견을 부정적으로 받아서는 안됩니다.대답에 잘못된 정보가 포함되어 있으면 향후 독자에게 해를 미칠 수 있으므로 지적해야합니다. – user694733

관련 문제