rpm/debugedit-canon-fix.diff

366 lines
8.8 KiB
Diff

Subject: Fix path canonicalization issues in debugedit
This patch fixes multiple problems with path canonicalization in
debugedit. This version of debugedit is taken from the dwarftools repository.
---
tools/debugedit.c | 165 ++++++++++++++++++++++++++----------------------------
1 file changed, 82 insertions(+), 83 deletions(-)
Index: tools/debugedit.c
===================================================================
--- tools/debugedit.c.orig
+++ tools/debugedit.c
@@ -471,13 +471,13 @@ has_prefix (const char *str,
{
int str_len;
int prefix_len;
-
+
str_len = strlen (str);
prefix_len = strlen (prefix);
if (str_len < prefix_len)
return 0;
-
+
return strncmp (str, prefix, prefix_len) == 0;
}
@@ -485,9 +485,10 @@ static int
edit_dwarf2_line (DSO *dso, uint_32 off, char *comp_dir, int phase)
{
unsigned char *ptr = debug_sections[DEBUG_LINE].data, *dir;
- unsigned char **dirt;
+ char **dirt;
unsigned char *endsec = ptr + debug_sections[DEBUG_LINE].size;
unsigned char *endcu, *endprol;
+ char line_base;
unsigned char opcode_base;
uint_32 value, dirt_cnt;
size_t comp_dir_len = strlen (comp_dir);
@@ -496,9 +497,9 @@ edit_dwarf2_line (DSO *dso, uint_32 off,
if (phase != 0)
return 0;
-
+
ptr += off;
-
+
endcu = ptr + 4;
endcu += read_32 (ptr);
if (endcu == ptr + 0xffffffff)
@@ -521,7 +522,7 @@ edit_dwarf2_line (DSO *dso, uint_32 off,
value);
return 1;
}
-
+
endprol = ptr + 4;
endprol += read_32 (ptr);
if (endprol > endcu)
@@ -530,26 +531,27 @@ edit_dwarf2_line (DSO *dso, uint_32 off,
dso->filename);
return 1;
}
-
+
+ line_base = (char) (ptr[2] & 0xff);
opcode_base = ptr[4];
ptr = dir = ptr + 4 + opcode_base;
-
+
/* dir table: */
value = 1;
while (*ptr != 0)
{
- ptr = strchr (ptr, 0) + 1;
+ ptr = (unsigned char *)strchr ((char *)ptr, 0) + 1;
++value;
}
- dirt = (unsigned char **) alloca (value * sizeof (unsigned char *));
+ dirt = (char **) alloca (value * sizeof (char *));
dirt[0] = ".";
dirt_cnt = 1;
ptr = dir;
while (*ptr != 0)
{
- dirt[dirt_cnt++] = ptr;
- ptr = strchr (ptr, 0) + 1;
+ dirt[dirt_cnt++] = (char *)ptr;
+ ptr = (unsigned char *)strchr ((char *)ptr, 0) + 1;
}
ptr++;
@@ -559,8 +561,8 @@ edit_dwarf2_line (DSO *dso, uint_32 off,
char *s, *file;
size_t file_len, dir_len;
- file = ptr;
- ptr = strchr (ptr, 0) + 1;
+ file = (char *)ptr;
+ ptr = (unsigned char *)strchr ((char *)ptr, 0) + 1;
value = read_uleb128 (ptr);
if (value >= dirt_cnt)
@@ -629,7 +631,7 @@ edit_dwarf2_line (DSO *dso, uint_32 off,
}
free (s);
-
+
read_uleb128 (ptr);
read_uleb128 (ptr);
}
@@ -661,7 +663,7 @@ edit_dwarf2_line (DSO *dso, uint_32 off,
if (dest_dir)
{
- unsigned char *srcptr, *buf = NULL;
+ char *srcptr, *srcstart, *buf = NULL;
size_t base_len = strlen (base_dir);
size_t dest_len = strlen (dest_dir);
size_t shrank = 0;
@@ -675,12 +677,16 @@ edit_dwarf2_line (DSO *dso, uint_32 off,
ptr = dir;
}
else
- ptr = srcptr = dir;
- unsigned char *srcstart=srcptr;
+ {
+ ptr = dir;
+ srcptr = (char *)dir;
+ }
+
+ srcstart = srcptr;
while (*srcptr != 0)
{
- size_t len = strlen (srcptr) + 1;
- const unsigned char *readptr = srcptr;
+ size_t len = strlen (srcptr);
+ const char *readptr = srcptr;
if (*srcptr == '/' && has_prefix (srcptr, base_dir))
{
@@ -689,39 +695,28 @@ edit_dwarf2_line (DSO *dso, uint_32 off,
memcpy (ptr, dest_dir, dest_len);
ptr += dest_len;
readptr += base_len;
- }
+ }
srcptr += len;
shrank += srcptr - readptr;
- canonicalize_path (readptr, ptr);
- len = strlen (ptr) + 1;
+ canonicalize_path (readptr, (char *)ptr);
+ len = strlen ((char *)ptr);
+
+/*
+ if ((srcptr - readptr) > len)
+ error(0, 0,"canonicalization unexpectedly shrank (%lu): \"%s\"\n",
+ (long unsigned int)(srcptr - readptr) - len, ptr);
+*/
+
shrank -= len;
ptr += len;
- elf_flagdata (debug_sections[DEBUG_STR].elf_data,
- ELF_C_SET, ELF_F_DIRTY);
- }
-
- if (shrank > 0)
- {
- if (--shrank == 0)
- error (EXIT_FAILURE, 0,
- "canonicalization unexpectedly shrank by one character");
- memset (ptr, 'X', shrank);
- ptr += shrank;
- *ptr++ = '\0';
+ elf_flagdata (debug_sections[DEBUG_STR].elf_data,
+ ELF_C_SET, ELF_F_DIRTY);
+ ++ptr;
+ ++srcptr;
}
- 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;
@@ -741,21 +736,30 @@ edit_dwarf2_line (DSO *dso, uint_32 off,
elf_flagdata (debug_sections[DEBUG_STR].elf_data,
ELF_C_SET, ELF_F_DIRTY);
}
- else if (ptr != srcptr)
+ else if ((char *)ptr != srcptr)
memmove (ptr, srcptr, len);
srcptr += len;
ptr += len;
- dir = srcptr;
+ dir = (unsigned char *)srcptr;
read_uleb128 (srcptr);
read_uleb128 (srcptr);
read_uleb128 (srcptr);
if (ptr != dir)
- memmove (ptr, dir, srcptr - dir);
- ptr += srcptr - dir;
+ memmove (ptr, dir, (unsigned char *)srcptr - dir);
+ ptr += (unsigned char *)srcptr - dir;
}
*ptr = '\0';
free (buf);
}
+
+ /* move the line number program */
+ ptr++;
+ if (ptr != endprol)
+ memmove(ptr, endprol, endcu - endprol);
+
+ /* fill the rest of the section with a NOP opcode */
+ ptr += endcu - endprol;
+ memset(ptr, opcode_base - line_base, endcu - ptr);
return 0;
}
@@ -767,17 +771,13 @@ edit_attributes (DSO *dso, unsigned char
int i;
uint_32 list_offs;
int found_list_offs;
- unsigned char *comp_dir;
-
- comp_dir = NULL;
- list_offs = 0;
- found_list_offs = 0;
+ char *comp_dir;
+
for (i = 0; i < t->nattr; ++i)
{
uint_32 form = t->attr[i].form;
uint_32 len = 0;
int base_len, dest_len;
-
while (1)
{
@@ -791,56 +791,55 @@ edit_attributes (DSO *dso, unsigned char
}
if (t->attr[i].attr == DW_AT_comp_dir)
- {
+ {
if ( form == DW_FORM_string )
- {
+ {
free (comp_dir);
- comp_dir = strdup (ptr);
-
- if (phase == 1 && dest_dir && has_prefix (ptr, base_dir))
- {
+ comp_dir = strdup ((char *)ptr);
+
+ if (phase == 1 && dest_dir
+ && has_prefix ((char *)ptr, base_dir))
+ {
base_len = strlen (base_dir);
dest_len = strlen (dest_dir);
-
+
memcpy (ptr, dest_dir, dest_len);
if (dest_len < base_len)
- {
+ {
memset(ptr + dest_len, '/',
base_len - dest_len);
-
- }
+ }
elf_flagdata (debug_sections[DEBUG_INFO].elf_data,
ELF_C_SET, ELF_F_DIRTY);
- }
- }
-
+ }
+ }
else if (form == DW_FORM_strp &&
debug_sections[DEBUG_STR].data)
- {
+ {
char *dir;
- dir = debug_sections[DEBUG_STR].data
- + do_read_32_relocated (ptr);
+ dir = (char *)debug_sections[DEBUG_STR].data
+ + do_read_32_relocated (ptr);
free (comp_dir);
comp_dir = strdup (dir);
if (phase == 1 && dest_dir && has_prefix (dir, base_dir))
- {
+ {
base_len = strlen (base_dir);
dest_len = strlen (dest_dir);
-
+
memcpy (dir, dest_dir, dest_len);
if (dest_len < base_len)
- {
+ {
memmove (dir + dest_len, dir + base_len,
strlen (dir + base_len) + 1);
- }
+ }
elf_flagdata (debug_sections[DEBUG_STR].elf_data,
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
@@ -848,9 +847,9 @@ edit_attributes (DSO *dso, unsigned char
&& debug_sections[DEBUG_STR].data)
{
char *name;
-
- name = debug_sections[DEBUG_STR].data
- + do_read_32_relocated (ptr);
+
+ name = (char *)debug_sections[DEBUG_STR].data
+ + do_read_32_relocated (ptr);
if (*name == '/' && comp_dir == NULL)
{
char *enddir = strrchr (name, '/');
@@ -869,7 +868,7 @@ edit_attributes (DSO *dso, unsigned char
{
base_len = strlen (base_dir);
dest_len = strlen (dest_dir);
-
+
memcpy (name, dest_dir, dest_len);
if (dest_len < base_len)
{
@@ -913,7 +912,7 @@ edit_attributes (DSO *dso, unsigned char
ptr += 4;
break;
case DW_FORM_string:
- ptr = strchr (ptr, '\0') + 1;
+ ptr = (unsigned char *)strchr ((char *)ptr, '\0') + 1;
break;
case DW_FORM_indirect:
form = read_uleb128 (ptr);