summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2003-01-27 17:45:53 +0000
committerjbj <devnull@localhost>2003-01-27 17:45:53 +0000
commit4cab573997627bc9210a4c345da380a3ba83d2b8 (patch)
tree0f4f85ba81c9dc2e6b1dd7eafb4f5954930432ec /tools
parentc87fa0b0298dda7ae49e3b079a7d464934188fe2 (diff)
downloadrpm-4cab573997627bc9210a4c345da380a3ba83d2b8.tar.gz
rpm-4cab573997627bc9210a4c345da380a3ba83d2b8.tar.bz2
rpm-4cab573997627bc9210a4c345da380a3ba83d2b8.zip
- fix: more debugedit.c problems.
CVS patchset: 6029 CVS date: 2003/01/27 17:45:53
Diffstat (limited to 'tools')
-rw-r--r--tools/debugedit.c136
1 files changed, 121 insertions, 15 deletions
diff --git a/tools/debugedit.c b/tools/debugedit.c
index cea971243..26f4f544a 100644
--- a/tools/debugedit.c
+++ b/tools/debugedit.c
@@ -38,6 +38,8 @@
#include "hashtab.h"
+#define DW_TAG_partial_unit 0x3c
+
char *base_dir = NULL;
char *dest_dir = NULL;
char *list_file = NULL;
@@ -424,6 +426,7 @@ edit_dwarf2_line (DSO *dso, uint_32 off, char *comp_dir, int phase)
unsigned char opcode_base;
uint_32 value, dirt_cnt;
size_t comp_dir_len = strlen (comp_dir);
+ size_t abs_file_cnt = 0, abs_dir_cnt = 0;
if (phase != 0)
return 0;
@@ -509,7 +512,11 @@ edit_dwarf2_line (DSO *dso, uint_32 off, char *comp_dir, int phase)
return 1;
}
if (*file == '/')
- memcpy (s, file, file_len + 1);
+ {
+ memcpy (s, file, file_len + 1);
+ if (dest_dir && has_prefix (file, base_dir))
+ ++abs_file_cnt;
+ }
else if (*dirt[value] == '/')
{
memcpy (s, dirt[value], dir_len);
@@ -556,28 +563,90 @@ edit_dwarf2_line (DSO *dso, uint_32 off, char *comp_dir, int phase)
read_uleb128 (ptr);
read_uleb128 (ptr);
}
+ ++ptr;
if (dest_dir)
{
- ptr = dir;
- while (*ptr != 0)
+ unsigned char *srcptr, *buf = NULL;
+ size_t base_len = strlen (base_dir);
+ size_t dest_len = strlen (dest_dir);
+
+ if (dest_len == base_len)
+ abs_file_cnt = 0;
+ if (abs_file_cnt)
+ {
+ srcptr = buf = malloc (ptr - dir);
+ memcpy (srcptr, dir, ptr - dir);
+ ptr = dir;
+ }
+ else
+ ptr = srcptr = dir;
+ while (*srcptr != 0)
{
- if (*ptr == '/' && has_prefix (ptr, base_dir))
+ size_t len = strlen (srcptr) + 1;
+
+ if (*srcptr == '/' && has_prefix (srcptr, base_dir))
{
- size_t base_len = strlen (base_dir);
- size_t dest_len = strlen (dest_dir);
+ memcpy (ptr, dest_dir, dest_len);
+ if (dest_len < base_len)
+ {
+ memmove (ptr + dest_len, srcptr + base_len,
+ len - base_len);
+ ptr += dest_len - base_len;
+ ++abs_dir_cnt;
+ }
+ elf_flagdata (debug_sections[DEBUG_STR].elf_data,
+ ELF_C_SET, ELF_F_DIRTY);
+ }
+ else if (ptr != srcptr)
+ memmove (ptr, srcptr, len);
+ srcptr += len;
+ ptr += len;
+ }
+
+ if (abs_dir_cnt + abs_file_cnt != 0)
+ {
+ size_t len = (abs_dir_cnt + abs_file_cnt) * (base_len - dest_len);
+ if (len == 1)
+ error (EXIT_FAILURE, 0, "-b arg has to be either the same length as -d arg, or more than 1 char shorter");
+ memset (ptr, 'X', len - 1);
+ ptr += len - 1;
+ *ptr++ = '\0';
+ }
+ *ptr++ = '\0';
+ ++srcptr;
+
+ while (*srcptr != 0)
+ {
+ size_t len = strlen (srcptr) + 1;
+
+ if (*srcptr == '/' && has_prefix (srcptr, base_dir))
+ {
memcpy (ptr, dest_dir, dest_len);
if (dest_len < base_len)
{
- memmove (ptr + dest_len, ptr + base_len,
- strlen (dir + base_len) + 1);
+ memmove (ptr + dest_len, srcptr + base_len,
+ len - base_len);
+ ptr += dest_len - base_len;
}
elf_flagdata (debug_sections[DEBUG_STR].elf_data,
ELF_C_SET, ELF_F_DIRTY);
}
- ptr = strchr (ptr, 0) + 1;
+ else if (ptr != srcptr)
+ memmove (ptr, srcptr, len);
+ srcptr += len;
+ ptr += len;
+ dir = srcptr;
+ read_uleb128 (srcptr);
+ read_uleb128 (srcptr);
+ read_uleb128 (srcptr);
+ if (ptr != dir)
+ memmove (ptr, dir, srcptr - dir);
+ ptr += srcptr - dir;
}
+ *ptr = '\0';
+ free (buf);
}
return 0;
}
@@ -613,13 +682,14 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
}
}
- if (debug_sections[DEBUG_STR].data &&
- t->attr[i].attr == DW_AT_comp_dir &&
- form == DW_FORM_strp)
+ if (t->attr[i].attr == DW_AT_comp_dir &&
+ form == DW_FORM_strp &&
+ debug_sections[DEBUG_STR].data)
{
char *dir;
dir = debug_sections[DEBUG_STR].data + do_read_32 (ptr);
+ free (comp_dir);
comp_dir = strdup (dir);
if (phase == 1 && dest_dir && has_prefix (dir, base_dir))
@@ -637,7 +707,45 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
ELF_C_SET, ELF_F_DIRTY);
}
}
-
+ else if ((t->tag == DW_TAG_compile_unit
+ || t->tag == DW_TAG_partial_unit)
+ && t->attr[i].attr == DW_AT_name
+ && form == DW_FORM_strp
+ && debug_sections[DEBUG_STR].data)
+ {
+ char *name;
+
+ name = debug_sections[DEBUG_STR].data + do_read_32 (ptr);
+ if (*name == '/' && comp_dir == NULL)
+ {
+ char *enddir = strrchr (name, '/');
+
+ if (enddir != name)
+ {
+ comp_dir = malloc (enddir - name + 1);
+ memcpy (comp_dir, name, enddir - name);
+ comp_dir [enddir - name] = '\0';
+ }
+ else
+ comp_dir = strdup ("/");
+ }
+
+ if (phase == 1 && dest_dir && has_prefix (name, base_dir))
+ {
+ base_len = strlen (base_dir);
+ dest_len = strlen (dest_dir);
+
+ memcpy (name, dest_dir, dest_len);
+ if (dest_len < base_len)
+ {
+ memmove (name + dest_len, name + base_len,
+ strlen (name + base_len) + 1);
+ }
+ elf_flagdata (debug_sections[DEBUG_STR].elf_data,
+ ELF_C_SET, ELF_F_DIRTY);
+ }
+ }
+
switch (form)
{
case DW_FORM_addr:
@@ -1115,5 +1223,3 @@ main (int argc, char *argv[])
return 0;
}
-
-