]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Check DW_OP_addr relocations
authorPetr Machata <pmachata@redhat.com>
Mon, 16 Feb 2009 16:57:02 +0000 (17:57 +0100)
committerPetr Machata <pmachata@redhat.com>
Mon, 16 Feb 2009 16:57:02 +0000 (17:57 +0100)
* and add support for address-like relocations in general

src/dwarflint.c
src/dwarflint.h

index 09da37fd761d16de74cfbee4e66b324519bf318b..65df847759df93ae663628634cc486a011905302 100644 (file)
@@ -2447,16 +2447,23 @@ relocate_one (struct relocation_data *reloc, GElf_Rela *rela,
       uint64_t section_index = symbol->st_shndx;
 
       /* It's target value, not section offset.  */
-      if (offset_into == rel_value)
+      if (offset_into == rel_value
+         || offset_into == rel_address)
        {
-         /* If a target value is what's expected, then complain
-            if it's not either SHN_ABS, an SHF_ALLOC section, or
-            SHN_UNDEF.  */
-         if (section_index != SHN_ABS && section_index != SHN_UNDEF)
+         /* If a target value is what's expected, then complain if
+            it's not either SHN_ABS, an SHF_ALLOC section, or
+            SHN_UNDEF.  For data forms of address_size, an SHN_UNDEF
+            reloc is acceptable, otherwise reject it.  */
+         if (!(section_index == SHN_ABS
+               || (offset_into == rel_address && section_index == SHN_UNDEF)))
            {
-             Elf_Scn *scn = elf_getscn (elf, section_index);
+             Elf_Scn *scn;
              GElf_Shdr shdr_mem, *shdr;
-             if (scn == NULL)
+             if (offset_into != rel_address && section_index == SHN_UNDEF)
+               wr_error (&reloc_where,
+                           ": relocation of an address is formed against SHN_UNDEF section"
+                           " (index %" PRId64 ").\n", section_index);
+             else if ((scn = elf_getscn (elf, section_index)) == NULL)
                wr_error (&reloc_where,
                          ": couldn't obtain associated section #%" PRId64 ".\n",
                          section_index);
@@ -2485,8 +2492,9 @@ relocate_one (struct relocation_data *reloc, GElf_Rela *rela,
                ? strdup (where_fmt (&WHERE (id, NULL), NULL)) : "(?)";
              char *wh2 = strdup (where_fmt (&WHERE (offset_into, NULL), NULL));
              wr_error (&reloc_where,
-                       ": relocation references section %s, but %s was expected.\n",
-                       wh1, wh2);
+                       ": relocation references section %s, but %s was expected"
+                       " (section index: %" PRId64 ").\n",
+                       wh1, wh2, section_index);
              free (wh2);
              if (id != sec_invalid)
                free (wh1);
@@ -2587,6 +2595,9 @@ reloc_target_loc (uint8_t opcode)
     case DW_OP_call4:
       return sec_info;
 
+    case DW_OP_addr:
+      return rel_address;
+
     case DW_OP_call_ref:
       assert (!"Can't handle call_ref!");
     };
index 290b4dd66c081cccf618a26464d12338c932f3ed..b05ee992773450feac766d2121a503b090899bbd 100644 (file)
@@ -24,6 +24,7 @@ extern "C"
     rel_value,         /* For relocations, this denotes that the
                           relocation is applied to taget value, not a
                           section offset.  */
+    rel_address,       /* Same as above, but for addresses.  */
 
     /* Debuginfo sections:  */
     sec_info,