]>
Commit | Line | Data |
---|---|---|
f412e1b4 PS |
1 | 2007-09-23 Jan Kratochvil <jan.kratochvil@redhat.com> |
2 | ||
3 | * elfcode.h (NAME(_bfd_elf,bfd_from_remote_memory)): New variables | |
4 | X_SHDR_SHSTRTAB and I_SHDR_SHSTRTAB. Fixed the CONTENTS_SIZE trimming | |
5 | check for its aligned size between the last segment and still before | |
6 | the section header end. Added variables check to cover also the | |
7 | section header string table. | |
8 | ||
9 | --- gdb-7.4.50.20120120-orig/bfd/elfcode.h 2012-02-29 09:17:08.000000000 +0100 | |
10 | +++ gdb-7.4.50.20120120/bfd/elfcode.h 2012-02-29 10:23:03.000000000 +0100 | |
11 | @@ -1621,6 +1621,8 @@ NAME(_bfd_elf,bfd_from_remote_memory) | |
12 | Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ | |
13 | Elf_External_Phdr *x_phdrs; | |
14 | Elf_Internal_Phdr *i_phdrs, *last_phdr; | |
15 | + Elf_External_Shdr *x_shdrs; | |
16 | + Elf_Internal_Shdr *i_shdrs; | |
17 | bfd *nbfd; | |
18 | struct bfd_in_memory *bim; | |
19 | int contents_size; | |
20 | @@ -1740,24 +1742,46 @@ NAME(_bfd_elf,bfd_from_remote_memory) | |
21 | ||
22 | /* Trim the last segment so we don't bother with zeros in the last page | |
23 | that are off the end of the file. However, if the extra bit in that | |
24 | - page includes the section headers, keep them. */ | |
25 | - if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz | |
26 | - && (bfd_vma) contents_size >= (i_ehdr.e_shoff | |
27 | - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) | |
28 | + page includes the section headers os the section header string table, | |
29 | + keep them. */ | |
30 | + if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz) | |
31 | + contents_size = last_phdr->p_offset + last_phdr->p_filesz; | |
32 | + | |
33 | + if ((bfd_vma) contents_size < i_ehdr.e_shoff | |
34 | + + i_ehdr.e_shnum * i_ehdr.e_shentsize) | |
35 | + contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; | |
36 | + | |
37 | + /* Verify also all the sections fit into CONTENTS_SIZE. */ | |
38 | + | |
39 | + x_shdrs = bfd_malloc (i_ehdr.e_shnum * (sizeof *x_shdrs + sizeof *i_shdrs)); | |
40 | + if (x_shdrs == NULL) | |
41 | { | |
42 | - contents_size = last_phdr->p_offset + last_phdr->p_filesz; | |
43 | - if ((bfd_vma) contents_size < (i_ehdr.e_shoff | |
44 | - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) | |
45 | - contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; | |
46 | + free (x_phdrs); | |
47 | + bfd_set_error (bfd_error_no_memory); | |
48 | + return NULL; | |
49 | } | |
50 | + err = target_read_memory (ehdr_vma + i_ehdr.e_shoff, (bfd_byte *) x_shdrs, | |
51 | + i_ehdr.e_shnum * sizeof *x_shdrs); | |
52 | + if (err) | |
53 | + i_shdrs = NULL; | |
54 | else | |
55 | - contents_size = last_phdr->p_offset + last_phdr->p_filesz; | |
56 | + { | |
57 | + i_shdrs = (Elf_Internal_Shdr *) &x_shdrs[i_ehdr.e_shnum]; | |
58 | + for (i = 0; i < i_ehdr.e_shnum; ++i) | |
59 | + { | |
60 | + elf_swap_shdr_in (templ, &x_shdrs[i], &i_shdrs[i]); | |
61 | + | |
62 | + if ((bfd_vma) contents_size < i_shdrs[i].sh_offset + i_shdrs[i].sh_size) | |
63 | + contents_size = i_shdrs[i].sh_offset + i_shdrs[i].sh_size; | |
64 | + } | |
65 | + } | |
66 | ||
67 | /* Now we know the size of the whole image we want read in. */ | |
68 | contents = (bfd_byte *) bfd_zmalloc (contents_size); | |
69 | if (contents == NULL) | |
70 | { | |
71 | free (x_phdrs); | |
72 | + free (x_shdrs); | |
73 | bfd_set_error (bfd_error_no_memory); | |
74 | return NULL; | |
75 | } | |
76 | @@ -1776,6 +1800,7 @@ NAME(_bfd_elf,bfd_from_remote_memory) | |
77 | if (err) | |
78 | { | |
79 | free (x_phdrs); | |
80 | + free (x_shdrs); | |
81 | free (contents); | |
82 | bfd_set_error (bfd_error_system_call); | |
83 | errno = err; | |
84 | @@ -1784,10 +1809,32 @@ NAME(_bfd_elf,bfd_from_remote_memory) | |
85 | } | |
86 | free (x_phdrs); | |
87 | ||
88 | - /* If the segments visible in memory didn't include the section headers, | |
89 | + if (i_shdrs) | |
90 | + { | |
91 | + memcpy (contents + i_ehdr.e_shoff, x_shdrs, | |
92 | + i_ehdr.e_shnum * sizeof *x_shdrs); | |
93 | + | |
94 | + for (i = 0; i < i_ehdr.e_shnum; ++i) | |
95 | + { | |
96 | + bfd_vma start = i_shdrs[i].sh_offset; | |
97 | + bfd_vma end = i_shdrs[i].sh_offset + i_shdrs[i].sh_size; | |
98 | + | |
99 | + if (end > (bfd_vma) contents_size) | |
100 | + end = contents_size; | |
101 | + err = target_read_memory (ehdr_vma + start, contents + start, | |
102 | + end - start); | |
103 | + if (err) | |
104 | + { | |
105 | + i_shdrs = NULL; | |
106 | + break; | |
107 | + } | |
108 | + } | |
109 | + } | |
110 | + free (x_shdrs); | |
111 | + | |
112 | + /* If the segments readable in memory didn't include the section headers, | |
113 | then clear them from the file header. */ | |
114 | - if ((bfd_vma) contents_size < (i_ehdr.e_shoff | |
115 | - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) | |
116 | + if (i_shdrs == NULL) | |
117 | { | |
118 | memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff); | |
119 | memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum); |