@@ -33,44 +33,86 @@ static unsigned int hex(char c)
33
33
return c - 'A' + 10 ;
34
34
}
35
35
36
- static size_t read_objdump_line (const char * line , size_t line_len , void * buf ,
37
- size_t len )
36
+ static size_t read_objdump_chunk (const char * * line , unsigned char * * buf ,
37
+ size_t * buf_len )
38
38
{
39
- const char * p ;
40
- size_t i , j = 0 ;
41
-
42
- /* Skip to a colon */
43
- p = strchr (line , ':' );
44
- if (!p )
45
- return 0 ;
46
- i = p + 1 - line ;
39
+ size_t bytes_read = 0 ;
40
+ unsigned char * chunk_start = * buf ;
47
41
48
42
/* Read bytes */
49
- while (j < len ) {
43
+ while (* buf_len > 0 ) {
50
44
char c1 , c2 ;
51
45
52
- /* Skip spaces */
53
- for (; i < line_len ; i ++ ) {
54
- if (!isspace (line [i ]))
55
- break ;
56
- }
57
46
/* Get 2 hex digits */
58
- if (i >= line_len || !isxdigit (line [i ]))
47
+ c1 = * (* line )++ ;
48
+ if (!isxdigit (c1 ))
59
49
break ;
60
- c1 = line [ i ++ ] ;
61
- if (i >= line_len || !isxdigit (line [ i ] ))
50
+ c2 = * ( * line ) ++ ;
51
+ if (!isxdigit (c2 ))
62
52
break ;
63
- c2 = line [i ++ ];
64
- /* Followed by a space */
65
- if (i < line_len && line [i ] && !isspace (line [i ]))
53
+
54
+ /* Store byte and advance buf */
55
+ * * buf = (hex (c1 ) << 4 ) | hex (c2 );
56
+ (* buf )++ ;
57
+ (* buf_len )-- ;
58
+ bytes_read ++ ;
59
+
60
+ /* End of chunk? */
61
+ if (isspace (* * line ))
66
62
break ;
67
- /* Store byte */
68
- * (unsigned char * )buf = (hex (c1 ) << 4 ) | hex (c2 );
69
- buf += 1 ;
70
- j ++ ;
71
63
}
64
+
65
+ /*
66
+ * objdump will display raw insn as LE if code endian
67
+ * is LE and bytes_per_chunk > 1. In that case reverse
68
+ * the chunk we just read.
69
+ *
70
+ * see disassemble_bytes() at binutils/objdump.c for details
71
+ * how objdump chooses display endian)
72
+ */
73
+ if (bytes_read > 1 && !bigendian ()) {
74
+ unsigned char * chunk_end = chunk_start + bytes_read - 1 ;
75
+ unsigned char tmp ;
76
+
77
+ while (chunk_start < chunk_end ) {
78
+ tmp = * chunk_start ;
79
+ * chunk_start = * chunk_end ;
80
+ * chunk_end = tmp ;
81
+ chunk_start ++ ;
82
+ chunk_end -- ;
83
+ }
84
+ }
85
+
86
+ return bytes_read ;
87
+ }
88
+
89
+ static size_t read_objdump_line (const char * line , unsigned char * buf ,
90
+ size_t buf_len )
91
+ {
92
+ const char * p ;
93
+ size_t ret , bytes_read = 0 ;
94
+
95
+ /* Skip to a colon */
96
+ p = strchr (line , ':' );
97
+ if (!p )
98
+ return 0 ;
99
+ p ++ ;
100
+
101
+ /* Skip initial spaces */
102
+ while (* p ) {
103
+ if (!isspace (* p ))
104
+ break ;
105
+ p ++ ;
106
+ }
107
+
108
+ do {
109
+ ret = read_objdump_chunk (& p , & buf , & buf_len );
110
+ bytes_read += ret ;
111
+ p ++ ;
112
+ } while (ret > 0 );
113
+
72
114
/* return number of successfully read bytes */
73
- return j ;
115
+ return bytes_read ;
74
116
}
75
117
76
118
static int read_objdump_output (FILE * f , void * buf , size_t * len , u64 start_addr )
@@ -95,7 +137,7 @@ static int read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr)
95
137
}
96
138
97
139
/* read objdump data into temporary buffer */
98
- read_bytes = read_objdump_line (line , ret , tmp , sizeof (tmp ));
140
+ read_bytes = read_objdump_line (line , tmp , sizeof (tmp ));
99
141
if (!read_bytes )
100
142
continue ;
101
143
@@ -152,7 +194,7 @@ static int read_via_objdump(const char *filename, u64 addr, void *buf,
152
194
153
195
ret = read_objdump_output (f , buf , & len , addr );
154
196
if (len ) {
155
- pr_debug ("objdump read too few bytes\n" );
197
+ pr_debug ("objdump read too few bytes: %zd \n" , len );
156
198
if (!ret )
157
199
ret = len ;
158
200
}
0 commit comments