1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
|
Upstream-Status: Backport
Index: elfutils-0.155/backends/arm_init.c
===================================================================
--- elfutils-0.155.orig/backends/arm_init.c
+++ elfutils-0.155/backends/arm_init.c
@@ -35,21 +35,32 @@
#define RELOC_PREFIX R_ARM_
#include "libebl_CPU.h"
+#include "libebl_arm.h"
+
/* This defines the common reloc hooks based on arm_reloc.def. */
#include "common-reloc.c"
const char *
arm_init (elf, machine, eh, ehlen)
- Elf *elf __attribute__ ((unused));
+ Elf *elf;
GElf_Half machine __attribute__ ((unused));
Ebl *eh;
size_t ehlen;
{
+ int soft_float = 0;
+
/* Check whether the Elf_BH object has a sufficent size. */
if (ehlen < sizeof (Ebl))
return NULL;
+ if (elf) {
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+ if (ehdr && (ehdr->e_flags & EF_ARM_SOFT_FLOAT))
+ soft_float = 1;
+ }
+
/* We handle it. */
eh->name = "ARM";
arm_init_reloc (eh);
@@ -61,7 +72,10 @@ arm_init (elf, machine, eh, ehlen)
HOOK (eh, core_note);
HOOK (eh, auxv_info);
HOOK (eh, check_object_attribute);
- HOOK (eh, return_value_location);
+ if (soft_float)
+ eh->return_value_location = arm_return_value_location_soft;
+ else
+ eh->return_value_location = arm_return_value_location_hard;
return MODVERSION;
}
Index: elfutils-0.155/backends/arm_regs.c
===================================================================
--- elfutils-0.155.orig/backends/arm_regs.c
+++ elfutils-0.155/backends/arm_regs.c
@@ -31,6 +31,7 @@
#endif
#include <string.h>
+#include <stdio.h>
#include <dwarf.h>
#define BACKEND arm_
@@ -61,7 +62,15 @@ arm_register_info (Ebl *ebl __attribute_
namelen = 2;
break;
- case 10 ... 12:
+ case 10 ... 11:
+ name[0] = 'r';
+ name[1] = '1';
+ name[2] = regno % 10 + '0';
+ namelen = 3;
+ break;
+
+ case 12:
+ *type = DW_ATE_unsigned;
name[0] = 'r';
name[1] = '1';
name[2] = regno % 10 + '0';
@@ -76,6 +85,9 @@ arm_register_info (Ebl *ebl __attribute_
break;
case 16 + 0 ... 16 + 7:
+ /* AADWARF says that there are no registers in that range,
+ * but gcc maps FPA registers here
+ */
regno += 96 - 16;
/* Fall through. */
case 96 + 0 ... 96 + 7:
@@ -87,11 +99,139 @@ arm_register_info (Ebl *ebl __attribute_
namelen = 2;
break;
+ case 64 + 0 ... 64 + 9:
+ *setname = "VFP";
+ *bits = 32;
+ *type = DW_ATE_float;
+ name[0] = 's';
+ name[1] = regno - 64 + '0';
+ namelen = 2;
+ break;
+
+ case 64 + 10 ... 64 + 31:
+ *setname = "VFP";
+ *bits = 32;
+ *type = DW_ATE_float;
+ name[0] = 's';
+ name[1] = (regno - 64) / 10 + '0';
+ name[2] = (regno - 64) % 10 + '0';
+ namelen = 3;
+ break;
+
+ case 104 + 0 ... 104 + 7:
+ /* XXX TODO:
+ * This can be either intel wireless MMX general purpose/control
+ * registers or xscale accumulator, which have different usage.
+ * We only have the intel wireless MMX here now.
+ * The name needs to be changed for the xscale accumulator too. */
+ *setname = "MMX";
+ *type = DW_ATE_unsigned;
+ *bits = 32;
+ memcpy(name, "wcgr", 4);
+ name[4] = regno - 104 + '0';
+ namelen = 5;
+ break;
+
+ case 112 + 0 ... 112 + 9:
+ *setname = "MMX";
+ *type = DW_ATE_unsigned;
+ *bits = 64;
+ name[0] = 'w';
+ name[1] = 'r';
+ name[2] = regno - 112 + '0';
+ namelen = 3;
+ break;
+
+ case 112 + 10 ... 112 + 15:
+ *setname = "MMX";
+ *type = DW_ATE_unsigned;
+ *bits = 64;
+ name[0] = 'w';
+ name[1] = 'r';
+ name[2] = '1';
+ name[3] = regno - 112 - 10 + '0';
+ namelen = 4;
+ break;
+
case 128:
+ *setname = "special";
*type = DW_ATE_unsigned;
return stpcpy (name, "spsr") + 1 - name;
+ case 129:
+ *setname = "special";
+ *type = DW_ATE_unsigned;
+ return stpcpy(name, "spsr_fiq") + 1 - name;
+
+ case 130:
+ *setname = "special";
+ *type = DW_ATE_unsigned;
+ return stpcpy(name, "spsr_irq") + 1 - name;
+
+ case 131:
+ *setname = "special";
+ *type = DW_ATE_unsigned;
+ return stpcpy(name, "spsr_abt") + 1 - name;
+
+ case 132:
+ *setname = "special";
+ *type = DW_ATE_unsigned;
+ return stpcpy(name, "spsr_und") + 1 - name;
+
+ case 133:
+ *setname = "special";
+ *type = DW_ATE_unsigned;
+ return stpcpy(name, "spsr_svc") + 1 - name;
+
+ case 144 ... 150:
+ *setname = "integer";
+ *type = DW_ATE_signed;
+ *bits = 32;
+ return sprintf(name, "r%d_usr", regno - 144 + 8) + 1;
+
+ case 151 ... 157:
+ *setname = "integer";
+ *type = DW_ATE_signed;
+ *bits = 32;
+ return sprintf(name, "r%d_fiq", regno - 151 + 8) + 1;
+
+ case 158 ... 159:
+ *setname = "integer";
+ *type = DW_ATE_signed;
+ *bits = 32;
+ return sprintf(name, "r%d_irq", regno - 158 + 13) + 1;
+
+ case 160 ... 161:
+ *setname = "integer";
+ *type = DW_ATE_signed;
+ *bits = 32;
+ return sprintf(name, "r%d_abt", regno - 160 + 13) + 1;
+
+ case 162 ... 163:
+ *setname = "integer";
+ *type = DW_ATE_signed;
+ *bits = 32;
+ return sprintf(name, "r%d_und", regno - 162 + 13) + 1;
+
+ case 164 ... 165:
+ *setname = "integer";
+ *type = DW_ATE_signed;
+ *bits = 32;
+ return sprintf(name, "r%d_svc", regno - 164 + 13) + 1;
+
+ case 192 ... 199:
+ *setname = "MMX";
+ *bits = 32;
+ *type = DW_ATE_unsigned;
+ name[0] = 'w';
+ name[1] = 'c';
+ name[2] = regno - 192 + '0';
+ namelen = 3;
+ break;
+
case 256 + 0 ... 256 + 9:
+ /* XXX TODO: Neon also uses those registers and can contain
+ * both float and integers */
*setname = "VFP";
*type = DW_ATE_float;
*bits = 64;
Index: elfutils-0.155/backends/arm_retval.c
===================================================================
--- elfutils-0.155.orig/backends/arm_retval.c
+++ elfutils-0.155/backends/arm_retval.c
@@ -48,6 +48,13 @@ static const Dwarf_Op loc_intreg[] =
#define nloc_intreg 1
#define nloc_intregs(n) (2 * (n))
+/* f1 */ /* XXX TODO: f0 can also have number 96 if program was compiled with -mabi=aapcs */
+static const Dwarf_Op loc_fpreg[] =
+ {
+ { .atom = DW_OP_reg16 },
+ };
+#define nloc_fpreg 1
+
/* The return value is a structure and is actually stored in stack space
passed in a hidden argument by the caller. But, the compiler
helpfully returns the address of that space in r0. */
@@ -58,8 +65,9 @@ static const Dwarf_Op loc_aggregate[] =
#define nloc_aggregate 1
-int
-arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+static int
+arm_return_value_location_ (Dwarf_Die *functypedie, const Dwarf_Op **locp,
+ int soft_float)
{
/* Start with the function's type, and get the DW_AT_type attribute,
which is the type of the return value. */
@@ -112,14 +120,31 @@ arm_return_value_location (Dwarf_Die *fu
else
return -1;
}
+ if (tag == DW_TAG_base_type)
+ {
+ Dwarf_Word encoding;
+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+ &attr_mem), &encoding) != 0)
+ return -1;
+
+ if ((encoding == DW_ATE_float) && !soft_float)
+ {
+ *locp = loc_fpreg;
+ if (size <= 8)
+ return nloc_fpreg;
+ goto aggregate;
+ }
+ }
if (size <= 16)
{
intreg:
*locp = loc_intreg;
return size <= 4 ? nloc_intreg : nloc_intregs ((size + 3) / 4);
}
+ /* fall through. */
aggregate:
+ /* XXX TODO sometimes aggregates are returned in r0 (-mabi=aapcs) */
*locp = loc_aggregate;
return nloc_aggregate;
@@ -138,3 +163,18 @@ arm_return_value_location (Dwarf_Die *fu
DWARF and might be valid. */
return -2;
}
+
+/* return location for -mabi=apcs-gnu -msoft-float */
+int
+arm_return_value_location_soft (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+ return arm_return_value_location_ (functypedie, locp, 1);
+}
+
+/* return location for -mabi=apcs-gnu -mhard-float (current default) */
+int
+arm_return_value_location_hard (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+ return arm_return_value_location_ (functypedie, locp, 0);
+}
+
Index: elfutils-0.155/libelf/elf.h
===================================================================
--- elfutils-0.155.orig/libelf/elf.h
+++ elfutils-0.155/libelf/elf.h
@@ -2281,6 +2281,9 @@ typedef Elf32_Addr Elf32_Conflict;
#define EF_ARM_EABI_VER4 0x04000000
#define EF_ARM_EABI_VER5 0x05000000
+/* EI_OSABI values */
+#define ELFOSABI_ARM_AEABI 64 /* Contains symbol versioning. */
+
/* Additional symbol types for Thumb. */
#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */
#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */
@@ -2298,12 +2301,19 @@ typedef Elf32_Addr Elf32_Conflict;
/* Processor specific values for the Phdr p_type field. */
#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */
+#define PT_ARM_UNWIND PT_ARM_EXIDX
/* Processor specific values for the Shdr sh_type field. */
#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */
#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */
#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */
+/* Processor specific values for the Dyn d_tag field. */
+#define DT_ARM_RESERVED1 (DT_LOPROC + 0)
+#define DT_ARM_SYMTABSZ (DT_LOPROC + 1)
+#define DT_ARM_PREEMTMAB (DT_LOPROC + 2)
+#define DT_ARM_RESERVED2 (DT_LOPROC + 3)
+#define DT_ARM_NUM 4
/* ARM relocs. */
@@ -2336,12 +2346,75 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */
#define R_ARM_GOT32 26 /* 32 bit GOT entry */
#define R_ARM_PLT32 27 /* 32 bit PLT address */
+#define R_ARM_CALL 28
+#define R_ARM_JUMP24 29
+#define R_ARM_THM_JUMP24 30
+#define R_ARM_BASE_ABS 31
#define R_ARM_ALU_PCREL_7_0 32
#define R_ARM_ALU_PCREL_15_8 33
#define R_ARM_ALU_PCREL_23_15 34
#define R_ARM_LDR_SBREL_11_0 35
#define R_ARM_ALU_SBREL_19_12 36
#define R_ARM_ALU_SBREL_27_20 37
+#define R_ARM_TARGET1 38
+#define R_ARM_SBREL31 39
+#define R_ARM_V4BX 40
+#define R_ARM_TARGET2 41
+#define R_ARM_PREL31 42
+#define R_ARM_MOVW_ABS_NC 43
+#define R_ARM_MOVT_ABS 44
+#define R_ARM_MOVW_PREL_NC 45
+#define R_ARM_MOVT_PREL 46
+#define R_ARM_THM_MOVW_ABS_NC 47
+#define R_ARM_THM_MOVT_ABS 48
+#define R_ARM_THM_MOVW_PREL_NC 49
+#define R_ARM_THM_MOVT_PREL 50
+#define R_ARM_THM_JUMP19 51
+#define R_ARM_THM_JUMP6 52
+#define R_ARM_THM_ALU_PREL_11_0 53
+#define R_ARM_THM_PC12 54
+#define R_ARM_ABS32_NO 55
+#define R_ARM_REL32_NO 56
+#define R_ARM_ALU_PC_G0_NC 57
+#define R_ARM_ALU_PC_G0 58
+#define R_ARM_ALU_PC_G1_NC 59
+#define R_ARM_ALU_PC_G1 60
+#define R_ARM_ALU_PC_G2 61
+#define R_ARM_LDR_PC_G1 62
+#define R_ARM_LDR_PC_G2 63
+#define R_ARM_LDRS_PC_G0 64
+#define R_ARM_LDRS_PC_G1 65
+#define R_ARM_LDRS_PC_G2 66
+#define R_ARM_LDC_PC_G0 67
+#define R_ARM_LDC_PC_G1 68
+#define R_ARM_LDC_PC_G2 69
+#define R_ARM_ALU_SB_G0_NC 70
+#define R_ARM_ALU_SB_G0 71
+#define R_ARM_ALU_SB_G1_NC 72
+#define R_ARM_ALU_SB_G1 73
+#define R_ARM_ALU_SB_G2 74
+#define R_ARM_LDR_SB_G0 75
+#define R_ARM_LDR_SB_G1 76
+#define R_ARM_LDR_SB_G2 77
+#define R_ARM_LDRS_SB_G0 78
+#define R_ARM_LDRS_SB_G1 79
+#define R_ARM_LDRS_SB_G2 80
+#define R_ARM_LDC_G0 81
+#define R_ARM_LDC_G1 82
+#define R_ARM_LDC_G2 83
+#define R_ARM_MOVW_BREL_NC 84
+#define R_ARM_MOVT_BREL 85
+#define R_ARM_MOVW_BREL 86
+#define R_ARM_THM_MOVW_BREL_NC 87
+#define R_ARM_THM_MOVT_BREL 88
+#define R_ARM_THM_MOVW_BREL 89
+/* 90-93 unallocated */
+#define R_ARM_PLT32_ABS 94
+#define R_ARM_GOT_ABS 95
+#define R_ARM_GOT_PREL 96
+#define R_ARM_GOT_BREL12 97
+#define R_ARM_GOTOFF12 98
+#define R_ARM_GOTRELAX 99
#define R_ARM_TLS_GOTDESC 90
#define R_ARM_TLS_CALL 91
#define R_ARM_TLS_DESCSEQ 92
@@ -2360,6 +2433,13 @@ typedef Elf32_Addr Elf32_Conflict;
static TLS block offset */
#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static
TLS block */
+#define R_ARM_TLS_LDO12 109
+#define R_ARM_TLS_LE12 110
+#define R_ARM_TLS_IE12GP 111
+/* 112 - 127 private range */
+#define R_ARM_ME_TOO 128|/* obsolete */
+
+
#define R_ARM_THM_TLS_DESCSEQ 129
#define R_ARM_IRELATIVE 160
#define R_ARM_RXPC25 249
Index: elfutils-0.155/backends/libebl_arm.h
===================================================================
--- /dev/null
+++ elfutils-0.155/backends/libebl_arm.h
@@ -0,0 +1,9 @@
+#ifndef _LIBEBL_ARM_H
+#define _LIBEBL_ARM_H 1
+
+#include <libdw.h>
+
+extern int arm_return_value_location_soft(Dwarf_Die *, const Dwarf_Op **locp);
+extern int arm_return_value_location_hard(Dwarf_Die *, const Dwarf_Op **locp);
+
+#endif
|