blob: d4e4675ad52a7e847d0caf52dd6991c59f1058ce [file] [log] [blame]
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