Commit 4e1ef15091b6f42ac13c22e3acc45a9bd9cce852
Committed by
Tom Rini
1 parent
50b5639430
Exists in
v2017.01-smarct4x
and in
37 other branches
arm: semihosting: fix up compile bugs
There is currently a regression when using newer ARM64 compilers for semihosting: the way long types are inferred from context is no longer the same. The semihosting runtime uses long and size_t, so use this explicitly in the semihosting code and interface, and voila: the code now works again. Tested with aarch64-linux-gnu-gcc: Linaro GCC 4.9-2014.09. Cc: Darwin Rambo <drambo@broadcom.com> Cc: AKASHI Takahiro <takahiro.akashi@linaro.org> Cc: Mark Hambleton <mark.hambleton@arm.com> Cc: Tom Rini <trini@ti.com> Acked-by: Steve Rae <srae@broadcom.com> Suggested-by: Mark Hambleton <mark.hambleton@arm.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Showing 2 changed files with 53 additions and 50 deletions Side-by-side Diff
arch/arm/include/asm/semihosting.h
arch/arm/lib/semihosting.c
... | ... | @@ -23,17 +23,17 @@ |
23 | 23 | #define MODE_READ 0x0 |
24 | 24 | #define MODE_READBIN 0x1 |
25 | 25 | |
26 | -static int smh_read(int fd, void *memp, int len); | |
27 | -static int smh_open(const char *fname, char *modestr); | |
28 | -static int smh_close(int fd); | |
29 | -static int smh_len_fd(int fd); | |
26 | +static long smh_read(long fd, void *memp, size_t len); | |
27 | +static long smh_open(const char *fname, char *modestr); | |
28 | +static long smh_close(long fd); | |
29 | +static long smh_len_fd(long fd); | |
30 | 30 | |
31 | 31 | /* |
32 | 32 | * Call the handler |
33 | 33 | */ |
34 | -static int smh_trap(unsigned int sysnum, void *addr) | |
34 | +static long smh_trap(unsigned int sysnum, void *addr) | |
35 | 35 | { |
36 | - register int result asm("r0"); | |
36 | + register long result asm("r0"); | |
37 | 37 | #if defined(CONFIG_ARM64) |
38 | 38 | asm volatile ("hlt #0xf000" : "=r" (result) : "0"(sysnum), "r"(addr)); |
39 | 39 | #else |
... | ... | @@ -51,7 +51,9 @@ |
51 | 51 | */ |
52 | 52 | int smh_load(const char *fname, void *memp, int avail, int verbose) |
53 | 53 | { |
54 | - int ret, fd, len; | |
54 | + long ret; | |
55 | + long fd; | |
56 | + size_t len; | |
55 | 57 | |
56 | 58 | ret = -1; |
57 | 59 | |
58 | 60 | |
59 | 61 | |
60 | 62 | |
... | ... | @@ -61,21 +63,21 @@ |
61 | 63 | /* Open the file */ |
62 | 64 | fd = smh_open(fname, "rb"); |
63 | 65 | if (fd == -1) |
64 | - return ret; | |
66 | + return -1; | |
65 | 67 | |
66 | 68 | /* Get the file length */ |
67 | 69 | ret = smh_len_fd(fd); |
68 | 70 | if (ret == -1) { |
69 | 71 | smh_close(fd); |
70 | - return ret; | |
72 | + return -1; | |
71 | 73 | } |
72 | 74 | |
73 | 75 | /* Check that the file will fit in the supplied buffer */ |
74 | 76 | if (ret > avail) { |
75 | - printf("%s: ERROR ret %d, avail %u\n", __func__, ret, | |
77 | + printf("%s: ERROR ret %ld, avail %u\n", __func__, ret, | |
76 | 78 | avail); |
77 | 79 | smh_close(fd); |
78 | - return ret; | |
80 | + return -1; | |
79 | 81 | } |
80 | 82 | |
81 | 83 | len = ret; |
... | ... | @@ -87,7 +89,7 @@ |
87 | 89 | if (verbose) { |
88 | 90 | printf("\n%s\n", fname); |
89 | 91 | printf(" 0x%8p dest\n", memp); |
90 | - printf(" 0x%08x size\n", len); | |
92 | + printf(" 0x%08lx size\n", len); | |
91 | 93 | printf(" 0x%08x avail\n", avail); |
92 | 94 | } |
93 | 95 | } |
94 | 96 | |
95 | 97 | |
96 | 98 | |
97 | 99 | |
98 | 100 | |
99 | 101 | |
100 | 102 | |
101 | 103 | |
102 | 104 | |
103 | 105 | |
104 | 106 | |
105 | 107 | |
... | ... | @@ -101,54 +103,53 @@ |
101 | 103 | /* |
102 | 104 | * Read 'len' bytes of file into 'memp'. Returns 0 on success, else failure |
103 | 105 | */ |
104 | -static int smh_read(int fd, void *memp, int len) | |
106 | +static long smh_read(long fd, void *memp, size_t len) | |
105 | 107 | { |
106 | - int ret; | |
108 | + long ret; | |
107 | 109 | struct smh_read_s { |
108 | - int fd; | |
110 | + long fd; | |
109 | 111 | void *memp; |
110 | - int len; | |
112 | + size_t len; | |
111 | 113 | } read; |
112 | 114 | |
113 | - debug("%s: fd %d, memp %p, len %d\n", __func__, fd, memp, len); | |
115 | + debug("%s: fd %ld, memp %p, len %lu\n", __func__, fd, memp, len); | |
114 | 116 | |
115 | 117 | read.fd = fd; |
116 | 118 | read.memp = memp; |
117 | 119 | read.len = len; |
118 | 120 | |
119 | 121 | ret = smh_trap(SYSREAD, &read); |
120 | - if (ret == 0) { | |
121 | - return 0; | |
122 | - } else { | |
122 | + if (ret < 0) { | |
123 | 123 | /* |
124 | 124 | * The ARM handler allows for returning partial lengths, |
125 | 125 | * but in practice this never happens so rather than create |
126 | 126 | * hard to maintain partial read loops and such, just fail |
127 | 127 | * with an error message. |
128 | 128 | */ |
129 | - printf("%s: ERROR ret %d, fd %d, len %u memp %p\n", | |
129 | + printf("%s: ERROR ret %ld, fd %ld, len %lu memp %p\n", | |
130 | 130 | __func__, ret, fd, len, memp); |
131 | + return -1; | |
131 | 132 | } |
132 | - return ret; | |
133 | + | |
134 | + return 0; | |
133 | 135 | } |
134 | 136 | |
135 | 137 | /* |
136 | 138 | * Open a file on the host. Mode is "r" or "rb" currently. Returns a file |
137 | 139 | * descriptor or -1 on error. |
138 | 140 | */ |
139 | -static int smh_open(const char *fname, char *modestr) | |
141 | +static long smh_open(const char *fname, char *modestr) | |
140 | 142 | { |
141 | - int ret, fd, mode; | |
143 | + long fd; | |
144 | + unsigned long mode; | |
142 | 145 | struct smh_open_s { |
143 | 146 | const char *fname; |
144 | - unsigned int mode; | |
145 | - unsigned int len; | |
147 | + unsigned long mode; | |
148 | + size_t len; | |
146 | 149 | } open; |
147 | 150 | |
148 | 151 | debug("%s: file \'%s\', mode \'%s\'\n", __func__, fname, modestr); |
149 | 152 | |
150 | - ret = -1; | |
151 | - | |
152 | 153 | /* Check the file mode */ |
153 | 154 | if (!(strcmp(modestr, "r"))) { |
154 | 155 | mode = MODE_READ; |
... | ... | @@ -157,7 +158,7 @@ |
157 | 158 | } else { |
158 | 159 | printf("%s: ERROR mode \'%s\' not supported\n", __func__, |
159 | 160 | modestr); |
160 | - return ret; | |
161 | + return -1; | |
161 | 162 | } |
162 | 163 | |
163 | 164 | open.fname = fname; |
... | ... | @@ -167,7 +168,7 @@ |
167 | 168 | /* Open the file on the host */ |
168 | 169 | fd = smh_trap(SYSOPEN, &open); |
169 | 170 | if (fd == -1) |
170 | - printf("%s: ERROR fd %d for file %s\n", __func__, fd, | |
171 | + printf("%s: ERROR fd %ld for file %s\n", __func__, fd, | |
171 | 172 | fname); |
172 | 173 | |
173 | 174 | return fd; |
174 | 175 | |
175 | 176 | |
176 | 177 | |
177 | 178 | |
... | ... | @@ -176,17 +177,15 @@ |
176 | 177 | /* |
177 | 178 | * Close the file using the file descriptor |
178 | 179 | */ |
179 | -static int smh_close(int fd) | |
180 | +static long smh_close(long fd) | |
180 | 181 | { |
181 | - int ret; | |
182 | - long fdlong; | |
182 | + long ret; | |
183 | 183 | |
184 | - debug("%s: fd %d\n", __func__, fd); | |
184 | + debug("%s: fd %ld\n", __func__, fd); | |
185 | 185 | |
186 | - fdlong = (long)fd; | |
187 | - ret = smh_trap(SYSCLOSE, &fdlong); | |
186 | + ret = smh_trap(SYSCLOSE, &fd); | |
188 | 187 | if (ret == -1) |
189 | - printf("%s: ERROR fd %d\n", __func__, fd); | |
188 | + printf("%s: ERROR fd %ld\n", __func__, fd); | |
190 | 189 | |
191 | 190 | return ret; |
192 | 191 | } |
193 | 192 | |
194 | 193 | |
195 | 194 | |
196 | 195 | |
... | ... | @@ -194,17 +193,15 @@ |
194 | 193 | /* |
195 | 194 | * Get the file length from the file descriptor |
196 | 195 | */ |
197 | -static int smh_len_fd(int fd) | |
196 | +static long smh_len_fd(long fd) | |
198 | 197 | { |
199 | - int ret; | |
200 | - long fdlong; | |
198 | + long ret; | |
201 | 199 | |
202 | - debug("%s: fd %d\n", __func__, fd); | |
200 | + debug("%s: fd %ld\n", __func__, fd); | |
203 | 201 | |
204 | - fdlong = (long)fd; | |
205 | - ret = smh_trap(SYSFLEN, &fdlong); | |
202 | + ret = smh_trap(SYSFLEN, &fd); | |
206 | 203 | if (ret == -1) |
207 | - printf("%s: ERROR ret %d\n", __func__, ret); | |
204 | + printf("%s: ERROR ret %ld, fd %ld\n", __func__, ret, fd); | |
208 | 205 | |
209 | 206 | return ret; |
210 | 207 | } |
211 | 208 | |
212 | 209 | |
213 | 210 | |
214 | 211 | |
215 | 212 | |
... | ... | @@ -212,26 +209,32 @@ |
212 | 209 | /* |
213 | 210 | * Get the file length from the filename |
214 | 211 | */ |
215 | -int smh_len(const char *fname) | |
212 | +long smh_len(const char *fname) | |
216 | 213 | { |
217 | - int ret, fd, len; | |
214 | + long ret; | |
215 | + long fd; | |
216 | + long len; | |
218 | 217 | |
219 | 218 | debug("%s: file \'%s\'\n", __func__, fname); |
220 | 219 | |
221 | 220 | /* Open the file */ |
222 | 221 | fd = smh_open(fname, "rb"); |
223 | - if (fd == -1) | |
222 | + if (fd < 0) | |
224 | 223 | return fd; |
225 | 224 | |
226 | 225 | /* Get the file length */ |
227 | 226 | len = smh_len_fd(fd); |
227 | + if (len < 0) { | |
228 | + smh_close(fd); | |
229 | + return len; | |
230 | + } | |
228 | 231 | |
229 | 232 | /* Close the file */ |
230 | 233 | ret = smh_close(fd); |
231 | - if (ret == -1) | |
234 | + if (ret < 0) | |
232 | 235 | return ret; |
233 | 236 | |
234 | - debug("%s: returning len %d\n", __func__, len); | |
237 | + debug("%s: returning len %ld\n", __func__, len); | |
235 | 238 | |
236 | 239 | /* Return the file length (or -1 error indication) */ |
237 | 240 | return len; |