1 /* Needed for libelf */
2 #define _FILE_OFFSET_BITS 64
12 Elf32_Word debug_section;
14 Elf32_Off orig_offset;
15 } UnstripInfoSection32;
18 Elf64_Word debug_section;
20 Elf64_Off orig_offset;
21 } UnstripInfoSection64;
24 Elf32_Off orig_e_shoff;
26 UnstripInfoSection32 sections[1];
30 Elf64_Off orig_e_shoff;
32 UnstripInfoSection64 sections[1];
36 elf_32_to_file (uint32_t x, int file_is_little_endian)
38 volatile uint32_t out;
39 unsigned char *outbytes;
41 outbytes = (unsigned char *)&out;
42 if (file_is_little_endian)
44 outbytes[0] = (x >> 0) & 0xff;
45 outbytes[1] = (x >> 8) & 0xff;
46 outbytes[2] = (x >> 16) & 0xff;
47 outbytes[3] = (x >> 24) & 0xff;
51 outbytes[0] = (x >> 24) & 0xff;
52 outbytes[1] = (x >> 16) & 0xff;
53 outbytes[2] = (x >> 8) & 0xff;
54 outbytes[3] = (x >> 0) & 0xff;
61 elf_64_to_file (uint64_t x, int file_is_little_endian)
63 volatile uint64_t out;
64 unsigned char *outbytes;
67 outbytes = (unsigned char *)&out;
68 if (file_is_little_endian)
70 for (i = 0; i < 8; i++)
71 outbytes[i] = (x >> (8*i)) & 0xff;
75 for (i = 0; i < 8; i++)
76 outbytes[7-i] = (x >> (8*i)) & 0xff;
83 word32_to_file (Elf32_Word x, Elf *elf)
85 Elf32_Ehdr *ehdr = elf32_getehdr (elf);
86 return elf_32_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
90 off32_to_file (Elf32_Off x, Elf *elf)
92 Elf32_Ehdr *ehdr = elf32_getehdr (elf);
93 return elf_32_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
97 word64_to_file (Elf64_Word x, Elf *elf)
99 Elf64_Ehdr *ehdr = elf64_getehdr (elf);
100 return elf_32_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
104 off64_to_file (Elf64_Off x, Elf *elf)
106 Elf64_Ehdr *ehdr = elf64_getehdr (elf);
107 return elf_64_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
111 elf_32_from_file (uint32_t x, int file_is_little_endian)
113 unsigned char *inbytes;
115 inbytes = (unsigned char *)&x;
116 if (file_is_little_endian)
124 else /* big endian */
135 elf_64_from_file (uint64_t x, int file_is_little_endian)
137 unsigned char *inbytes;
139 inbytes = (unsigned char *)&x;
140 if (file_is_little_endian)
143 ((uint64_t)inbytes[0] << 0) |
144 ((uint64_t)inbytes[1] << 8) |
145 ((uint64_t)inbytes[2] << 16) |
146 ((uint64_t)inbytes[3] << 24) |
147 ((uint64_t)inbytes[4] << 32) |
148 ((uint64_t)inbytes[5] << 40) |
149 ((uint64_t)inbytes[6] << 48) |
150 ((uint64_t)inbytes[7] << 56);
152 else /* big endian */
155 ((uint64_t)inbytes[0] << 56) |
156 ((uint64_t)inbytes[1] << 48) |
157 ((uint64_t)inbytes[2] << 40) |
158 ((uint64_t)inbytes[3] << 32) |
159 ((uint64_t)inbytes[4] << 24) |
160 ((uint64_t)inbytes[5] << 16) |
161 ((uint64_t)inbytes[6] << 8) |
162 ((uint64_t)inbytes[7] << 0);
167 word32_from_file (Elf32_Word x, Elf *elf)
169 Elf32_Ehdr *ehdr = elf32_getehdr (elf);
170 return elf_32_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
174 off32_from_file (Elf32_Off x, Elf *elf)
176 Elf32_Ehdr *ehdr = elf32_getehdr (elf);
177 return elf_32_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
181 word64_from_file (Elf64_Word x, Elf *elf)
183 Elf64_Ehdr *ehdr = elf64_getehdr (elf);
184 return elf_32_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
188 off64_from_file (Elf64_Off x, Elf *elf)
190 Elf64_Ehdr *ehdr = elf64_getehdr (elf);
191 return elf_64_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
195 unstrip_info_to_data32 (UnstripInfo *info,
199 UnstripInfo32 *info32;
205 /* orig_e_shoff */ sizeof (Elf32_Off) +
206 /* n_sections */ sizeof (Elf32_Off) +
207 /* sections */ info->n_sections * sizeof (UnstripInfoSection32);
209 data->d_buf = calloc (1, data->d_size);
211 info32 = (UnstripInfo32 *) data->d_buf;
213 info32->orig_e_shoff = off32_to_file (info->orig_e_shoff, elf);
214 info32->n_sections = off32_to_file (info->n_sections, elf);
216 for (i = 0; i < info->n_sections; i++)
218 info32->sections[i].debug_section = word32_to_file (info->sections[i].debug_section, elf);
219 info32->sections[i].name = word32_to_file (info->sections[i].name, elf);
220 info32->sections[i].orig_offset = off32_to_file (info->sections[i].orig_offset, elf);
225 unstrip_info_to_data64 (UnstripInfo *info,
229 UnstripInfo64 *info64;
235 /* orig_e_shoff */ sizeof (Elf64_Off) +
236 /* n_sections */ sizeof (Elf64_Off) +
237 /* sections */ info->n_sections * sizeof (UnstripInfoSection64);
239 data->d_buf = calloc (1, data->d_size);
241 info64 = (UnstripInfo64 *) data->d_buf;
243 info64->orig_e_shoff = off64_to_file (info->orig_e_shoff, elf);
244 info64->n_sections = off64_to_file (info->n_sections, elf);
246 for (i = 0; i < info->n_sections; i++)
248 info64->sections[i].debug_section = word64_to_file (info->sections[i].debug_section, elf);
249 info64->sections[i].name = word64_to_file (info->sections[i].name, elf);
250 info64->sections[i].orig_offset = off64_to_file (info->sections[i].orig_offset, elf);
255 unstrip_info_to_data (UnstripInfo *info,
261 data->d_type = ELF_T_BYTE;
264 gelf_getehdr (elf, &ehdr);
265 if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
266 unstrip_info_to_data32 (info, elf, data);
267 else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
268 unstrip_info_to_data64 (info, elf, data);
270 fprintf (stderr, "Warning. unsupported elf class\n");
274 unstrip_info_from_data32 (UnstripInfo *info,
278 UnstripInfo32 *info32;
281 info32 = (UnstripInfo32 *) data->d_buf;
283 info->orig_e_shoff = off32_from_file (info32->orig_e_shoff, elf);
284 info->n_sections = off32_from_file (info32->n_sections, elf);
286 info->sections = calloc (info->n_sections, sizeof (UnstripInfoSection));
287 for (i = 0; i < info->n_sections; i++)
289 info->sections[i].debug_section = word32_from_file (info32->sections[i].debug_section, elf);
290 info->sections[i].name = word32_from_file (info32->sections[i].name, elf);
291 info->sections[i].orig_offset = off32_from_file (info32->sections[i].orig_offset, elf);
296 unstrip_info_from_data64 (UnstripInfo *info,
300 UnstripInfo64 *info64;
303 info64 = (UnstripInfo64 *) data->d_buf;
305 info->orig_e_shoff = off64_from_file (info64->orig_e_shoff, elf);
306 info->n_sections = off64_from_file (info64->n_sections, elf);
308 info->sections = calloc (info->n_sections, sizeof (UnstripInfoSection));
309 for (i = 0; i < info->n_sections; i++)
311 info->sections[i].debug_section = word64_from_file (info64->sections[i].debug_section, elf);
312 info->sections[i].name = word64_from_file (info64->sections[i].name, elf);
313 info->sections[i].orig_offset = off64_from_file (info64->sections[i].orig_offset, elf);
318 unstrip_info_from_data (Elf *elf,
325 info = malloc (sizeof (UnstripInfo));
327 gelf_getehdr (elf, &ehdr);
328 if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
329 unstrip_info_from_data32 (info, elf, data);
330 else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
331 unstrip_info_from_data64 (info, elf, data);
333 fprintf (stderr, "Warning. unsupported elf class\n");
339 debug_link_to_data32 (DebugLink *debuglink,
343 size_t namelen_aligned;
348 namelen_aligned = align_up (strlen(debuglink->filename) + 1, 4);
351 /* name */ namelen_aligned +
352 /* checksum */ sizeof (Elf32_Word);
354 data->d_buf = calloc (1, data->d_size);
356 strcpy (data->d_buf, debuglink->filename);
357 p = ((char *)data->d_buf) + namelen_aligned;
359 *(Elf32_Word *)p = word32_to_file (debuglink->checksum, elf);
363 debug_link_to_data64 (DebugLink *debuglink,
367 size_t namelen_aligned;
372 namelen_aligned = align_up (strlen(debuglink->filename) + 1, 4);
375 /* name */ namelen_aligned +
376 /* checksum */ sizeof (Elf64_Word);
378 data->d_buf = calloc (1, data->d_size);
380 strcpy (data->d_buf, debuglink->filename);
381 p = ((char *)data->d_buf) + namelen_aligned;
383 *(Elf64_Word *)p = word64_to_file (debuglink->checksum, elf);
387 debug_link_to_data (DebugLink *debuglink, Elf *elf, Elf_Data *data)
391 data->d_type = ELF_T_BYTE;
394 gelf_getehdr (elf, &ehdr);
395 if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
396 debug_link_to_data32 (debuglink, elf, data);
397 else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
398 debug_link_to_data64 (debuglink, elf, data);
400 fprintf (stderr, "Warning. unsupported elf class\n");
404 debug_link_from_data32 (DebugLink *debuglink,
408 size_t namelen_aligned;
411 debuglink->filename = strdup (data->d_buf);
413 namelen_aligned = align_up (strlen (debuglink->filename) + 1, 4);
415 p = ((char *)data->d_buf) + namelen_aligned;
417 debuglink->checksum = word32_from_file (*(Elf32_Word *)p, elf);
421 debug_link_from_data64 (DebugLink *debuglink,
425 size_t namelen_aligned;
428 debuglink->filename = strdup (data->d_buf);
430 namelen_aligned = align_up (strlen (debuglink->filename) + 1, 4);
432 p = ((char *)data->d_buf) + namelen_aligned;
434 debuglink->checksum = word64_from_file (*(Elf64_Word *)p, elf);
439 debug_link_from_data (Elf *elf, Elf_Data *data)
442 DebugLink *debuglink;
444 debuglink = malloc (sizeof (DebugLink));
446 gelf_getehdr (elf, &ehdr);
447 if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
448 debug_link_from_data32 (debuglink, elf, data);
449 else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
450 debug_link_from_data64 (debuglink, elf, data);
452 fprintf (stderr, "Warning. unsupported elf class\n");