raven-rhel6/rpm/rpm-4.8.0-debugedit-lazy-buildid.patch
2024-02-21 20:14:44 +06:00

468 lines
11 KiB
Diff

diff --git a/tools/debugedit.c b/tools/debugedit.c
index b9db7db..820e5aa 100644
--- a/tools/debugedit.c
+++ b/tools/debugedit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2005, 2007, 2009 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2005, 2007, 2009, 2010 Red Hat, Inc.
Written by Alexander Larsson <alexl@redhat.com>, 2002
Based on code by Jakub Jelinek <jakub@redhat.com>, 2001.
@@ -444,16 +444,24 @@ has_prefix (const char *str,
{
size_t str_len;
size_t prefix_len;
-
+
str_len = strlen (str);
prefix_len = strlen (prefix);
if (str_len < prefix_len)
return 0;
-
+
return strncmp (str, prefix, prefix_len) == 0;
}
+static int dirty_elf;
+static void
+dirty_section (unsigned int sec)
+{
+ elf_flagdata (debug_sections[sec].elf_data, ELF_C_SET, ELF_F_DIRTY);
+ dirty_elf = 1;
+}
+
static int
edit_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir, int phase)
{
@@ -468,9 +476,9 @@ edit_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir, int phase)
if (phase != 0)
return 0;
-
+
ptr += off;
-
+
endcu = ptr + 4;
endcu += read_32 (ptr);
if (endcu == ptr + 0xffffffff)
@@ -493,7 +501,7 @@ edit_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir, int phase)
value);
return 1;
}
-
+
endprol = ptr + 4;
endprol += read_32 (ptr);
if (endprol > endcu)
@@ -502,10 +510,10 @@ edit_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir, int phase)
dso->filename);
return 1;
}
-
+
opcode_base = ptr[4];
ptr = dir = ptr + 4 + opcode_base;
-
+
/* dir table: */
value = 1;
while (*ptr != 0)
@@ -600,12 +608,12 @@ edit_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir, int phase)
}
free (s);
-
+
read_uleb128 (ptr);
read_uleb128 (ptr);
}
++ptr;
-
+
if (dest_dir)
{
unsigned char *srcptr, *buf = NULL;
@@ -628,14 +636,16 @@ edit_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir, int phase)
size_t len = strlen ((char *)srcptr) + 1;
const unsigned char *readptr = srcptr;
+ char *orig = strdup ((const char *) srcptr);
+
if (*srcptr == '/' && has_prefix ((char *)srcptr, base_dir))
{
if (dest_len < base_len)
- ++abs_dir_cnt;
+ ++abs_dir_cnt;
memcpy (ptr, dest_dir, dest_len);
ptr += dest_len;
readptr += base_len;
- }
+ }
srcptr += len;
shrank += srcptr - readptr;
@@ -644,9 +654,10 @@ edit_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir, int phase)
shrank -= len;
ptr += len;
- elf_flagdata (debug_sections[DEBUG_STR].elf_data,
- ELF_C_SET, ELF_F_DIRTY);
- }
+ if (memcmp (orig, ptr - len, len))
+ dirty_section (DEBUG_STR);
+ free (orig);
+ }
if (shrank > 0)
{
@@ -654,7 +665,7 @@ edit_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir, int phase)
error (EXIT_FAILURE, 0,
"canonicalization unexpectedly shrank by one character");
else
- {
+ {
memset (ptr, 'X', shrank);
ptr += shrank;
*ptr++ = '\0';
@@ -687,8 +698,7 @@ edit_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir, int phase)
len - base_len);
ptr += dest_len - base_len;
}
- elf_flagdata (debug_sections[DEBUG_STR].elf_data,
- ELF_C_SET, ELF_F_DIRTY);
+ dirty_section (DEBUG_STR);
}
else if (ptr != srcptr)
memmove (ptr, srcptr, len);
@@ -708,8 +718,6 @@ edit_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir, int phase)
return 0;
}
-
-
static unsigned char *
edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
{
@@ -717,7 +725,7 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
uint32_t list_offs;
int found_list_offs;
char *comp_dir;
-
+
comp_dir = NULL;
list_offs = 0;
found_list_offs = 0;
@@ -726,7 +734,6 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
uint32_t form = t->attr[i].form;
size_t len = 0;
size_t base_len, dest_len;
-
while (1)
{
@@ -740,56 +747,53 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
}
if (t->attr[i].attr == DW_AT_comp_dir)
- {
- if ( form == DW_FORM_string )
- {
+ {
+ if (form == DW_FORM_string)
+ {
free (comp_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);
- }
- }
-
+
+ }
+ dirty_section (DEBUG_INFO);
+ }
+ }
else if (form == DW_FORM_strp &&
debug_sections[DEBUG_STR].data)
- {
+ {
char *dir;
dir = (char *) debug_sections[DEBUG_STR].data
- + do_read_32_relocated (ptr);
+ + 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);
- }
- }
- }
+ }
+ dirty_section (DEBUG_STR);
+ }
+ }
+ }
else if ((t->tag == DW_TAG_compile_unit
|| t->tag == DW_TAG_partial_unit)
&& t->attr[i].attr == DW_AT_name
@@ -797,9 +801,9 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
&& debug_sections[DEBUG_STR].data)
{
char *name;
-
+
name = (char *) debug_sections[DEBUG_STR].data
- + do_read_32_relocated (ptr);
+ + do_read_32_relocated (ptr);
if (*name == '/' && comp_dir == NULL)
{
char *enddir = strrchr (name, '/');
@@ -818,15 +822,14 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
{
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);
+ dirty_section (DEBUG_STR);
}
}
@@ -896,7 +899,7 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
if (form == DW_FORM_block1)
ptr += len;
-
+
break;
}
}
@@ -985,7 +988,7 @@ edit_dwarf2 (DSO *dso)
return 1;
}
- scn = dso->scn[i];
+ scn = dso->scn[i];
data = elf_rawdata (scn, NULL);
assert (data != NULL && data->d_buf != NULL);
assert (elf_rawdata (scn, data) == NULL);
@@ -1061,7 +1064,7 @@ edit_dwarf2 (DSO *dso)
int rtype;
i = debug_sections[DEBUG_INFO].relsec;
- scn = dso->scn[i];
+ scn = dso->scn[i];
data = elf_getdata (scn, NULL);
assert (data != NULL && data->d_buf != NULL);
assert (elf_getdata (scn, data) == NULL);
@@ -1179,13 +1182,13 @@ edit_dwarf2 (DSO *dso)
error (0, 0, "%s: 64-bit DWARF not supported", dso->filename);
return 1;
}
-
+
if (endcu > endsec)
{
error (0, 0, "%s: .debug_info too small", dso->filename);
return 1;
}
-
+
cu_version = read_16 (ptr);
if (cu_version != 2 && cu_version != 3)
{
@@ -1193,7 +1196,7 @@ edit_dwarf2 (DSO *dso)
cu_version);
return 1;
}
-
+
value = read_32_relocated (ptr);
if (value >= debug_sections[DEBUG_ABBREV].size)
{
@@ -1204,7 +1207,7 @@ edit_dwarf2 (DSO *dso)
dso->filename);
return 1;
}
-
+
if (ptr_size == 0)
{
ptr_size = read_1 (ptr);
@@ -1221,12 +1224,12 @@ edit_dwarf2 (DSO *dso)
dso->filename);
return 1;
}
-
+
abbrev = read_abbrev (dso,
debug_sections[DEBUG_ABBREV].data + value);
if (abbrev == NULL)
return 1;
-
+
while (ptr < endcu)
{
tag.entry = read_uleb128 (ptr);
@@ -1240,18 +1243,18 @@ edit_dwarf2 (DSO *dso)
htab_delete (abbrev);
return 1;
}
-
+
ptr = edit_attributes (dso, ptr, t, phase);
if (ptr == NULL)
break;
}
-
+
htab_delete (abbrev);
}
}
free (relbuf);
}
-
+
return 0;
}
@@ -1314,7 +1317,7 @@ fdopen_dso (int fd, const char *name)
}
elf_flagelf (elf, ELF_C_SET, ELF_F_LAYOUT);
-
+
memset (dso, 0, sizeof(DSO));
dso->elf = elf;
dso->ehdr = ehdr;
@@ -1368,6 +1371,9 @@ handle_build_id (DSO *dso, Elf_Data *build_id,
exit (1);
}
+ if (!dirty_elf)
+ goto print;
+
if (elf_update (dso->elf, ELF_C_NULL) < 0)
{
fprintf (stderr, "Failed to update file: %s\n",
@@ -1447,6 +1453,7 @@ handle_build_id (DSO *dso, Elf_Data *build_id,
elf_flagdata (build_id, ELF_C_SET, ELF_F_DIRTY);
+ print:
/* Now format the build ID bits in hex to print out. */
{
const uint8_t * id = (uint8_t *)build_id->d_buf + build_id_offset;
@@ -1471,7 +1478,7 @@ main (int argc, char *argv[])
size_t build_id_offset = 0, build_id_size = 0;
optCon = poptGetContext("debugedit", argc, (const char **)argv, optionsTable, 0);
-
+
while ((nextopt = poptGetNextOpt (optCon)) > 0 || nextopt == POPT_ERROR_BADOPT)
/* do nothing */ ;
@@ -1483,7 +1490,7 @@ main (int argc, char *argv[])
argv[0]);
exit (1);
}
-
+
args = poptGetArgs (optCon);
if (args == NULL || args[0] == NULL || args[1] != NULL)
{
@@ -1522,12 +1529,12 @@ main (int argc, char *argv[])
free (dest_dir);
dest_dir = p;
}
-
+
if (list_file != NULL)
{
list_file_fd = open (list_file, O_WRONLY|O_CREAT|O_APPEND, 0644);
}
-
+
file = args[0];
if (elf_version(EV_CURRENT) == EV_NONE)
@@ -1559,7 +1566,7 @@ main (int argc, char *argv[])
for (i = 1; i < dso->ehdr.e_shnum; i++)
{
const char *name;
-
+
switch (dso->shdr[i].sh_type)
{
case SHT_PROGBITS:
@@ -1588,7 +1595,7 @@ main (int argc, char *argv[])
Elf_Data src = dst;
src.d_buf = data->d_buf;
assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
- while ((char *) data->d_buf + data->d_size -
+ while ((char *) data->d_buf + data->d_size -
(char *) src.d_buf > (int) sizeof nh
&& elf32_xlatetom (&dst, &src, dso->ehdr.e_ident[EI_DATA]))
{
@@ -1599,7 +1606,7 @@ main (int argc, char *argv[])
&& !memcmp ((char *) src.d_buf + sizeof nh, "GNU", sizeof "GNU"))
{
build_id = data;
- build_id_offset = (char *) src.d_buf + len -
+ build_id_offset = (char *) src.d_buf + len -
(char *) data->d_buf;
build_id_size = nh.n_descsz;
break;
@@ -1633,7 +1640,7 @@ main (int argc, char *argv[])
/* Restore old access rights */
chmod (file, stat_buf.st_mode);
-
+
poptFreeContext (optCon);
return 0;