450 lines
13 KiB
Diff
450 lines
13 KiB
Diff
Upstream-Status: Backport
|
|
|
|
Index: elfutils-0.146/backends/arm_init.c
|
|
===================================================================
|
|
--- elfutils-0.146.orig/backends/arm_init.c 2009-04-21 14:50:01.000000000 +0000
|
|
+++ elfutils-0.146/backends/arm_init.c 2010-04-24 10:11:13.000000000 +0000
|
|
@@ -32,21 +32,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);
|
|
@@ -58,7 +69,10 @@
|
|
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.146/backends/arm_regs.c
|
|
===================================================================
|
|
--- elfutils-0.146.orig/backends/arm_regs.c 2009-04-21 14:50:01.000000000 +0000
|
|
+++ elfutils-0.146/backends/arm_regs.c 2010-04-24 10:11:13.000000000 +0000
|
|
@@ -28,6 +28,7 @@
|
|
#endif
|
|
|
|
#include <string.h>
|
|
+#include <stdio.h>
|
|
#include <dwarf.h>
|
|
|
|
#define BACKEND arm_
|
|
@@ -58,7 +59,15 @@
|
|
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';
|
|
@@ -73,6 +82,9 @@
|
|
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:
|
|
@@ -84,11 +96,139 @@
|
|
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.146/backends/arm_retval.c
|
|
===================================================================
|
|
--- elfutils-0.146.orig/backends/arm_retval.c 2010-01-12 16:57:54.000000000 +0000
|
|
+++ elfutils-0.146/backends/arm_retval.c 2010-04-24 10:11:13.000000000 +0000
|
|
@@ -45,6 +45,13 @@
|
|
#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. */
|
|
@@ -55,8 +62,9 @@
|
|
#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. */
|
|
@@ -109,14 +117,31 @@
|
|
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;
|
|
|
|
@@ -135,3 +160,18 @@
|
|
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.146/libelf/elf.h
|
|
===================================================================
|
|
--- elfutils-0.146.orig/libelf/elf.h 2010-04-24 10:11:11.000000000 +0000
|
|
+++ elfutils-0.146/libelf/elf.h 2010-04-24 10:11:13.000000000 +0000
|
|
@@ -2290,6 +2290,9 @@
|
|
#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. */
|
|
@@ -2307,12 +2310,19 @@
|
|
|
|
/* 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. */
|
|
|
|
@@ -2344,12 +2354,75 @@
|
|
#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_NOI 55
|
|
+#define R_ARM_REL32_NOI 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_GNU_VTENTRY 100
|
|
#define R_ARM_GNU_VTINHERIT 101
|
|
#define R_ARM_THM_PC11 102 /* thumb unconditional branch */
|
|
@@ -2364,6 +2437,12 @@
|
|
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_RXPC25 249
|
|
#define R_ARM_RSBREL32 250
|
|
#define R_ARM_THM_RPC22 251
|
|
Index: elfutils-0.146/backends/libebl_arm.h
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ elfutils-0.146/backends/libebl_arm.h 2010-04-24 10:11:13.000000000 +0000
|
|
@@ -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
|