~ubuntu-branches/ubuntu/quantal/enigmail/quantal-security

« back to all changes in this revision

Viewing changes to mozilla/config/elf-dynstr-gc.c

  • Committer: Package Import Robot
  • Author(s): Chris Coulson
  • Date: 2013-09-13 16:02:15 UTC
  • mfrom: (0.12.16)
  • Revision ID: package-import@ubuntu.com-20130913160215-u3g8nmwa0pdwagwc
Tags: 2:1.5.2-0ubuntu0.12.10.1
* New upstream release v1.5.2 for Thunderbird 24

* Build enigmail using a stripped down Thunderbird 17 build system, as it's
  now quite difficult to build the way we were doing previously, with the
  latest Firefox build system
* Add debian/patches/no_libxpcom.patch - Don't link against libxpcom, as it
  doesn't exist anymore (but exists in the build system)
* Add debian/patches/use_sdk.patch - Use the SDK version of xpt.py and
  friends
* Drop debian/patches/ipc-pipe_rename.diff (not needed anymore)
* Drop debian/patches/makefile_depth.diff (not needed anymore)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* elf_gc_dynst
 
2
 *
 
3
 * This is a program that removes unreferenced strings from the .dynstr
 
4
 * section in ELF shared objects. It also shrinks the .dynstr section and
 
5
 * relocates all symbols after it.
 
6
 *
 
7
 * This program was written and copyrighted by:
 
8
 *   Alexander Larsson <alla@lysator.liu.se>
 
9
 *
 
10
 *
 
11
 *
 
12
 * This Source Code Form is subject to the terms of the Mozilla Public
 
13
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 
14
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
15
 
 
16
 
 
17
#include <stdio.h>
 
18
#include <unistd.h>
 
19
#include <fcntl.h>
 
20
#include <sys/types.h>
 
21
#include <sys/stat.h>
 
22
#include <sys/mman.h>
 
23
 
 
24
#include <elf.h>
 
25
#include <glib.h>
 
26
#include <string.h>
 
27
 
 
28
 
 
29
Elf32_Ehdr *elf_header = NULL;
 
30
#define FILE_OFFSET(offset) ((unsigned char *)(elf_header) + (offset))
 
31
 
 
32
struct dynamic_symbol {
 
33
  Elf32_Word old_index;
 
34
  Elf32_Word new_index;
 
35
  char *string;
 
36
};
 
37
 
 
38
GHashTable *used_dynamic_symbols = NULL;
 
39
/* Data is dynamic_symbols, hashes on old_index */
 
40
Elf32_Word hole_index;
 
41
Elf32_Word hole_end;
 
42
Elf32_Word hole_len;
 
43
 
 
44
Elf32_Addr hole_addr_start;
 
45
Elf32_Addr hole_addr_remap_start;
 
46
Elf32_Addr hole_addr_remap_end;
 
47
 
 
48
int need_byteswap;
 
49
 
 
50
unsigned char machine_type;
 
51
 
 
52
Elf32_Word
 
53
read_word(Elf32_Word w)
 
54
{
 
55
  if (need_byteswap) 
 
56
    w = GUINT32_SWAP_LE_BE(w);
 
57
  return w;
 
58
}
 
59
 
 
60
Elf32_Sword
 
61
read_sword(Elf32_Sword w)
 
62
{
 
63
  if (need_byteswap) 
 
64
    w = (Elf32_Sword)GUINT32_SWAP_LE_BE((guint32)w);
 
65
  return w;
 
66
}
 
67
 
 
68
void 
 
69
write_word(Elf32_Word *ptr, Elf32_Word w)
 
70
{
 
71
  if (need_byteswap) 
 
72
    w = GUINT32_SWAP_LE_BE(w);
 
73
  *ptr = w;
 
74
}
 
75
 
 
76
Elf32_Half
 
77
read_half(Elf32_Half h)
 
78
{
 
79
  if (need_byteswap) 
 
80
    h = GUINT16_SWAP_LE_BE(h);
 
81
  return h;
 
82
}
 
83
 
 
84
void 
 
85
write_half(Elf32_Half *ptr, Elf32_Half h)
 
86
{
 
87
  if (need_byteswap) 
 
88
    h = GUINT16_SWAP_LE_BE(h);
 
89
  *ptr = h;
 
90
}
 
91
 
 
92
void
 
93
setup_byteswapping(unsigned char ei_data)
 
94
{
 
95
  need_byteswap = 0;
 
96
#if G_BYTE_ORDER == G_BIG_ENDIAN
 
97
  if (ei_data == ELFDATA2LSB)
 
98
    need_byteswap = 1;
 
99
#endif
 
100
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
 
101
  if (ei_data == ELFDATA2MSB)
 
102
    need_byteswap = 1;
 
103
#endif
 
104
}
 
105
 
 
106
 
 
107
Elf32_Shdr *
 
108
elf_find_section_num(int section_index)
 
109
{
 
110
  Elf32_Shdr *section;
 
111
  Elf32_Word sectionsize;
 
112
 
 
113
  section = (Elf32_Shdr *)FILE_OFFSET(read_word(elf_header->e_shoff));
 
114
  sectionsize = read_half(elf_header->e_shentsize);
 
115
 
 
116
  section = (Elf32_Shdr *)((char *)section + sectionsize*section_index);
 
117
 
 
118
  return section;
 
119
}
 
120
 
 
121
Elf32_Shdr *
 
122
elf_find_section_named(char *name)
 
123
{
 
124
  Elf32_Shdr *section;
 
125
  Elf32_Shdr *strtab_section;
 
126
  Elf32_Word sectionsize;
 
127
  int numsections;
 
128
  char *strtab;
 
129
  int i = 0;
 
130
 
 
131
  section = (Elf32_Shdr *)FILE_OFFSET(read_word(elf_header->e_shoff));
 
132
 
 
133
  strtab_section = elf_find_section_num(read_half(elf_header->e_shstrndx));
 
134
  
 
135
  strtab = (char *)FILE_OFFSET(read_word(strtab_section->sh_offset));
 
136
  
 
137
  sectionsize = read_half(elf_header->e_shentsize);
 
138
  numsections = read_half(elf_header->e_shnum);
 
139
 
 
140
  for (i=0;i<numsections;i++) {
 
141
    if (strcmp(&strtab[read_word(section->sh_name)], name) == 0) {
 
142
      return section;
 
143
    }
 
144
    section = (Elf32_Shdr *)((char *)section + sectionsize);
 
145
  }
 
146
  return NULL;
 
147
}
 
148
 
 
149
 
 
150
Elf32_Shdr *
 
151
elf_find_section(Elf32_Word sh_type)
 
152
{
 
153
  Elf32_Shdr *section;
 
154
  Elf32_Word sectionsize;
 
155
  int numsections;
 
156
  int i = 0;
 
157
 
 
158
  section = (Elf32_Shdr *)FILE_OFFSET(read_word(elf_header->e_shoff));
 
159
  sectionsize = read_half(elf_header->e_shentsize);
 
160
  numsections = read_half(elf_header->e_shnum);
 
161
 
 
162
  for (i=0;i<numsections;i++) {
 
163
    if (read_word(section->sh_type) == sh_type) {
 
164
      return section;
 
165
    }
 
166
    section = (Elf32_Shdr *)((char *)section + sectionsize);
 
167
  }
 
168
  return NULL;
 
169
}
 
170
 
 
171
Elf32_Shdr *
 
172
elf_find_next_higher_section(Elf32_Word offset)
 
173
{
 
174
  Elf32_Shdr *section;
 
175
  Elf32_Shdr *higher;
 
176
  Elf32_Word sectionsize;
 
177
  int numsections;
 
178
  int i = 0;
 
179
 
 
180
  section = (Elf32_Shdr *)FILE_OFFSET(read_word(elf_header->e_shoff));
 
181
  sectionsize = read_half(elf_header->e_shentsize);
 
182
  numsections = read_half(elf_header->e_shnum);
 
183
 
 
184
  higher = NULL;
 
185
 
 
186
  for (i=0;i<numsections;i++) {
 
187
    if (read_word(section->sh_offset) >= offset) {
 
188
      if (higher == NULL) {
 
189
        higher = section;
 
190
      } else if (read_word(section->sh_offset) < read_word(higher->sh_offset)) {
 
191
        higher = section;
 
192
      }
 
193
    }
 
194
    
 
195
    section = (Elf32_Shdr *)((char *)section + sectionsize);
 
196
  }
 
197
  
 
198
  return higher;
 
199
}
 
200
 
 
201
Elf32_Word
 
202
vma_to_offset(Elf32_Addr addr)
 
203
{
 
204
  Elf32_Shdr *section;
 
205
  Elf32_Shdr *higher;
 
206
  Elf32_Word sectionsize;
 
207
  int numsections;
 
208
  int i = 0;
 
209
 
 
210
  section = (Elf32_Shdr *)FILE_OFFSET(read_word(elf_header->e_shoff));
 
211
  sectionsize = read_half(elf_header->e_shentsize);
 
212
  numsections = read_half(elf_header->e_shnum);
 
213
 
 
214
  higher = NULL;
 
215
 
 
216
  for (i=0;i<numsections;i++) {
 
217
    if ( (addr >= read_word(section->sh_addr)) &&
 
218
         (addr < read_word(section->sh_addr) + read_word(section->sh_size)) ) {
 
219
      return read_word(section->sh_offset) + (addr - read_word(section->sh_addr));
 
220
    }
 
221
    
 
222
    section = (Elf32_Shdr *)((char *)section + sectionsize);
 
223
  }
 
224
 
 
225
  fprintf(stderr, "Warning, unable to convert address %d (0x%x) to file offset\n",
 
226
         addr, addr);
 
227
  return 0;
 
228
}
 
229
 
 
230
 
 
231
void
 
232
find_segment_addr_min_max(Elf32_Word file_offset,
 
233
                          Elf32_Addr *start, Elf32_Addr *end)
 
234
{
 
235
  Elf32_Phdr *segment;
 
236
  Elf32_Word segmentsize;
 
237
  int numsegments;
 
238
  int i = 0;
 
239
 
 
240
  segment = (Elf32_Phdr *)FILE_OFFSET(read_word(elf_header->e_phoff));
 
241
  segmentsize = read_half(elf_header->e_phentsize);
 
242
  numsegments = read_half(elf_header->e_phnum);
 
243
 
 
244
  for (i=0;i<numsegments;i++) {
 
245
    if ((file_offset >= read_word(segment->p_offset)) &&
 
246
        (file_offset < read_word(segment->p_offset) + read_word(segment->p_filesz)))  {
 
247
      *start = read_word(segment->p_vaddr);
 
248
      *end = read_word(segment->p_vaddr) + read_word(segment->p_memsz);
 
249
      return;
 
250
    }
 
251
 
 
252
    segment = (Elf32_Phdr *)((char *)segment + segmentsize);
 
253
  }
 
254
  fprintf(stderr, "Error: Couldn't find segment in find_segment_addr_min_max()\n");
 
255
}
 
256
 
 
257
void *
 
258
dynamic_find_tag(Elf32_Shdr *dynamic, Elf32_Sword d_tag)
 
259
{
 
260
  int i;
 
261
  Elf32_Dyn *element;
 
262
 
 
263
  element = (Elf32_Dyn *)FILE_OFFSET(read_word(dynamic->sh_offset));
 
264
  for (i=0; read_sword(element[i].d_tag) != DT_NULL; i++) {
 
265
    if (read_sword(element[i].d_tag) == d_tag) {
 
266
      return FILE_OFFSET(read_word(element[i].d_un.d_ptr));
 
267
    }
 
268
  }
 
269
  
 
270
  return NULL;
 
271
}
 
272
 
 
273
Elf32_Word
 
274
fixup_offset(Elf32_Word offset)
 
275
{
 
276
  if (offset >= hole_index) {
 
277
    return offset - hole_len;
 
278
  }
 
279
  return offset;
 
280
}
 
281
 
 
282
Elf32_Word
 
283
fixup_size(Elf32_Word offset, Elf32_Word size)
 
284
{
 
285
  /* Note: Doesn't handle the cases where the hole and the size intersect
 
286
     partially. */
 
287
  
 
288
  if ( (hole_index >= offset) &&
 
289
       (hole_index < offset + size)){
 
290
    return size - hole_len;
 
291
  }
 
292
  
 
293
  return size;
 
294
}
 
295
 
 
296
Elf32_Addr
 
297
fixup_addr(Elf32_Addr addr)
 
298
{
 
299
  if (addr == 0)
 
300
    return 0;
 
301
 
 
302
  /*
 
303
  if ( (addr < hole_addr_remap_start) ||
 
304
       (addr >= hole_addr_remap_end))
 
305
    return addr;
 
306
  */
 
307
  
 
308
  if (addr >= hole_addr_start) {
 
309
    return addr - hole_len;
 
310
  }
 
311
  return addr;
 
312
}
 
313
 
 
314
Elf32_Word
 
315
fixup_addr_size(Elf32_Addr addr, Elf32_Word size)
 
316
{
 
317
  /* Note: Doesn't handle the cases where the hole and the size intersect
 
318
     partially. */
 
319
  /*
 
320
  if ( (addr < hole_addr_remap_start) ||
 
321
       (addr >= hole_addr_remap_end))
 
322
    return size;
 
323
  */
 
324
  if ( (hole_addr_start >= addr) &&
 
325
       (hole_addr_start < addr + size)){
 
326
    return size - hole_len;
 
327
  }
 
328
  
 
329
  return size;
 
330
}
 
331
 
 
332
void
 
333
possibly_add_string(int name_idx, const char *name)
 
334
{
 
335
  struct dynamic_symbol *dynamic_symbol;
 
336
  if (name_idx != 0) {
 
337
    dynamic_symbol = g_hash_table_lookup(used_dynamic_symbols, (gpointer) name_idx);
 
338
    
 
339
    if (dynamic_symbol == NULL) {
 
340
      
 
341
      dynamic_symbol = g_new(struct dynamic_symbol, 1);
 
342
      
 
343
      dynamic_symbol->old_index = name_idx;
 
344
      dynamic_symbol->new_index = 0;
 
345
      dynamic_symbol->string = g_strdup(name);
 
346
      
 
347
      g_hash_table_insert(used_dynamic_symbols, (gpointer)name_idx, dynamic_symbol);
 
348
      /*printf("added dynamic string: %s (%d)\n", dynamic_symbol->string, name_idx);*/
 
349
    }
 
350
  }
 
351
}
 
352
 
 
353
Elf32_Word
 
354
fixup_string(Elf32_Word old_idx)
 
355
{
 
356
  struct dynamic_symbol *dynamic_symbol;
 
357
 
 
358
  if (old_idx == 0)
 
359
    return 0;
 
360
  
 
361
  dynamic_symbol = g_hash_table_lookup(used_dynamic_symbols, (gpointer) old_idx);
 
362
 
 
363
  if (dynamic_symbol == NULL) {
 
364
    fprintf(stderr, "AAAAAAAAAAAARGH!? Unknown string found in fixup (index: %d)!\n", old_idx);
 
365
    return 0;
 
366
  }
 
367
  
 
368
  return dynamic_symbol->new_index;
 
369
}
 
370
 
 
371
 
 
372
 
 
373
void
 
374
add_strings_from_dynsym(Elf32_Shdr *dynsym, char *strtab)
 
375
{
 
376
  Elf32_Sym *symbol;
 
377
  Elf32_Sym *symbol_end;
 
378
  Elf32_Word entry_size;
 
379
  
 
380
 
 
381
  symbol = (Elf32_Sym *)FILE_OFFSET(read_word(dynsym->sh_offset));
 
382
  symbol_end = (Elf32_Sym *)FILE_OFFSET(read_word(dynsym->sh_offset) + read_word(dynsym->sh_size));
 
383
  entry_size = read_word(dynsym->sh_entsize);
 
384
 
 
385
  while (symbol < symbol_end) {
 
386
    int name_idx;
 
387
    struct dynamic_symbol *dynamic_symbol;
 
388
 
 
389
    name_idx = read_word(symbol->st_name);
 
390
    possibly_add_string(name_idx, &strtab[name_idx]);
 
391
 
 
392
    
 
393
    symbol = (Elf32_Sym *)((char *)symbol + entry_size);
 
394
  }
 
395
}
 
396
 
 
397
 
 
398
void
 
399
fixup_strings_in_dynsym(Elf32_Shdr *dynsym)
 
400
{
 
401
  Elf32_Sym *symbol;
 
402
  Elf32_Sym *symbol_end;
 
403
  Elf32_Word entry_size;
 
404
  
 
405
 
 
406
  symbol = (Elf32_Sym *)FILE_OFFSET(read_word(dynsym->sh_offset));
 
407
  symbol_end = (Elf32_Sym *)FILE_OFFSET(read_word(dynsym->sh_offset) + read_word(dynsym->sh_size));
 
408
  entry_size = read_word(dynsym->sh_entsize);
 
409
  
 
410
  while (symbol < symbol_end) {
 
411
    struct dynamic_symbol *dynamic_symbol;
 
412
 
 
413
    write_word(&symbol->st_name,
 
414
               fixup_string(read_word(symbol->st_name)));
 
415
                         
 
416
    symbol = (Elf32_Sym *)((char *)symbol + entry_size);
 
417
  }
 
418
}
 
419
 
 
420
 
 
421
void
 
422
add_strings_from_dynamic(Elf32_Shdr *dynamic, char *strtab)
 
423
{
 
424
  int i;
 
425
  int name_idx;
 
426
  Elf32_Dyn *element;
 
427
  Elf32_Word entry_size;
 
428
 
 
429
  entry_size = read_word(dynamic->sh_entsize);
 
430
  
 
431
 
 
432
  element = (Elf32_Dyn *)FILE_OFFSET(read_word(dynamic->sh_offset));
 
433
  while (read_sword(element->d_tag) != DT_NULL) {
 
434
 
 
435
    switch(read_sword(element->d_tag)) {
 
436
    case DT_NEEDED:
 
437
    case DT_SONAME:
 
438
    case DT_RPATH:
 
439
      name_idx = read_word(element->d_un.d_val);
 
440
      /*if (name_idx) printf("d_tag: %d\n", element->d_tag);*/
 
441
      possibly_add_string(name_idx, &strtab[name_idx]);
 
442
      break;
 
443
    default:
 
444
      ;
 
445
      /*printf("unhandled d_tag: %d (0x%x)\n", element->d_tag, element->d_tag);*/
 
446
    }
 
447
 
 
448
    element = (Elf32_Dyn *)((char *)element + entry_size);
 
449
  }
 
450
  
 
451
}
 
452
 
 
453
void
 
454
fixup_strings_in_dynamic(Elf32_Shdr *dynamic)
 
455
{
 
456
  int i;
 
457
  int name_idx;
 
458
  Elf32_Dyn *element;
 
459
  Elf32_Word entry_size;
 
460
 
 
461
  entry_size = read_word(dynamic->sh_entsize);
 
462
 
 
463
  element = (Elf32_Dyn *)FILE_OFFSET(read_word(dynamic->sh_offset));
 
464
  while (read_sword(element->d_tag) != DT_NULL) {
 
465
 
 
466
    switch(read_sword(element->d_tag)) {
 
467
    case DT_NEEDED:
 
468
    case DT_SONAME:
 
469
    case DT_RPATH:
 
470
      write_word(&element->d_un.d_val,
 
471
                 fixup_string(read_word(element->d_un.d_val)));
 
472
      break;
 
473
    default:
 
474
      ;
 
475
      /*printf("unhandled d_tag: %d (0x%x)\n", element->d_tag, element->d_tag);*/
 
476
    }
 
477
 
 
478
    element = (Elf32_Dyn *)((char *)element + entry_size);
 
479
  }
 
480
  
 
481
}
 
482
 
 
483
 
 
484
void
 
485
add_strings_from_ver_d(Elf32_Shdr *ver_d, char *strtab)
 
486
{
 
487
  Elf32_Verdaux *veraux;
 
488
  Elf32_Verdef *verdef;
 
489
  int num_aux;
 
490
  int name_idx;
 
491
  int i;
 
492
  int cont;
 
493
 
 
494
  verdef = (Elf32_Verdef *)FILE_OFFSET(read_word(ver_d->sh_offset));
 
495
 
 
496
  do {
 
497
    num_aux = read_half(verdef->vd_cnt);
 
498
    veraux = (Elf32_Verdaux *)((char *)verdef + read_word(verdef->vd_aux));
 
499
    for (i=0; i<num_aux; i++) {
 
500
      name_idx = read_word(veraux->vda_name);
 
501
      possibly_add_string(name_idx, &strtab[name_idx]);
 
502
      veraux = (Elf32_Verdaux *)((char *)veraux + read_word(veraux->vda_next));
 
503
    }
 
504
 
 
505
    cont = read_word(verdef->vd_next) != 0;
 
506
    verdef = (Elf32_Verdef *)((char *)verdef + read_word(verdef->vd_next));
 
507
  } while (cont);
 
508
  
 
509
}
 
510
 
 
511
void
 
512
fixup_strings_in_ver_d(Elf32_Shdr *ver_d)
 
513
{
 
514
  Elf32_Verdaux *veraux;
 
515
  Elf32_Verdef *verdef;
 
516
  int num_aux;
 
517
  int name_idx;
 
518
  int i;
 
519
  int cont;
 
520
 
 
521
  verdef = (Elf32_Verdef *)FILE_OFFSET(read_word(ver_d->sh_offset));
 
522
 
 
523
  do {
 
524
    num_aux = read_half(verdef->vd_cnt);
 
525
    veraux = (Elf32_Verdaux *)((char *)verdef + read_word(verdef->vd_aux));
 
526
    for (i=0; i<num_aux; i++) {
 
527
      write_word(&veraux->vda_name,
 
528
                 fixup_string(read_word(veraux->vda_name)));
 
529
      veraux = (Elf32_Verdaux *)((char *)veraux + read_word(veraux->vda_next));
 
530
    }
 
531
 
 
532
    cont = read_word(verdef->vd_next) != 0;
 
533
    verdef = (Elf32_Verdef *)((char *)verdef + read_word(verdef->vd_next));
 
534
  } while (cont);
 
535
  
 
536
}
 
537
 
 
538
void
 
539
add_strings_from_ver_r(Elf32_Shdr *ver_r, char *strtab)
 
540
{
 
541
  Elf32_Vernaux *veraux;
 
542
  Elf32_Verneed *verneed;
 
543
  int num_aux;
 
544
  int name_idx;
 
545
  int i;
 
546
  int cont;
 
547
 
 
548
  verneed = (Elf32_Verneed *)FILE_OFFSET(read_word(ver_r->sh_offset));
 
549
 
 
550
  do {
 
551
    name_idx = read_word(verneed->vn_file);
 
552
    possibly_add_string(name_idx, &strtab[name_idx]);
 
553
    num_aux = read_half(verneed->vn_cnt);
 
554
    veraux = (Elf32_Vernaux *)((char *)verneed + read_word(verneed->vn_aux));
 
555
    for (i=0; i<num_aux; i++) {
 
556
      name_idx = read_word(veraux->vna_name);
 
557
      possibly_add_string(name_idx, &strtab[name_idx]);
 
558
      veraux = (Elf32_Vernaux *)((char *)veraux + read_word(veraux->vna_next));
 
559
    }
 
560
 
 
561
    cont = read_word(verneed->vn_next) != 0;
 
562
    verneed = (Elf32_Verneed *)((char *)verneed + read_word(verneed->vn_next));
 
563
  } while (cont);
 
564
}
 
565
 
 
566
void
 
567
fixup_strings_in_ver_r(Elf32_Shdr *ver_r)
 
568
{
 
569
  Elf32_Vernaux *veraux;
 
570
  Elf32_Verneed *verneed;
 
571
  int num_aux;
 
572
  int name_idx;
 
573
  int i;
 
574
  int cont;
 
575
 
 
576
  verneed = (Elf32_Verneed *)FILE_OFFSET(read_word(ver_r->sh_offset));
 
577
 
 
578
  do {
 
579
    write_word(&verneed->vn_file,
 
580
               fixup_string(read_word(verneed->vn_file)));
 
581
    num_aux = read_half(verneed->vn_cnt);
 
582
    veraux = (Elf32_Vernaux *)((char *)verneed + read_word(verneed->vn_aux));
 
583
    for (i=0; i<num_aux; i++) {
 
584
      write_word(&veraux->vna_name,
 
585
                 fixup_string(read_word(veraux->vna_name)));
 
586
      veraux = (Elf32_Vernaux *)((char *)veraux + read_word(veraux->vna_next));
 
587
    }
 
588
 
 
589
    cont = read_word(verneed->vn_next) != 0;
 
590
    verneed = (Elf32_Verneed *)((char *)verneed + read_word(verneed->vn_next));
 
591
  } while (cont);
 
592
}
 
593
 
 
594
gboolean sum_size(gpointer      key,
 
595
                  struct dynamic_symbol *sym,
 
596
                  int *size)
 
597
{
 
598
  *size += strlen(sym->string) + 1;
 
599
  return 1;
 
600
}
 
601
 
 
602
struct index_n_dynstr {
 
603
  int index;
 
604
  unsigned char *dynstr;
 
605
};
 
606
 
 
607
gboolean output_string(gpointer key,
 
608
                       struct dynamic_symbol *sym,
 
609
                       struct index_n_dynstr *x)
 
610
{
 
611
  sym->new_index = x->index;
 
612
  memcpy(x->dynstr + x->index, sym->string, strlen(sym->string) + 1);
 
613
  x->index += strlen(sym->string) + 1;
 
614
  return 1;
 
615
}
 
616
 
 
617
 
 
618
unsigned char *
 
619
generate_new_dynstr(Elf32_Word *size_out)
 
620
{
 
621
  int size;
 
622
  unsigned char *new_dynstr;
 
623
  struct index_n_dynstr x;
 
624
 
 
625
  size = 1; /* first a zero */
 
626
  g_hash_table_foreach  (used_dynamic_symbols,
 
627
                         (GHFunc)sum_size,
 
628
                         &size);
 
629
 
 
630
 
 
631
  new_dynstr = g_malloc(size);
 
632
 
 
633
  new_dynstr[0] = 0;
 
634
  x.index = 1;
 
635
  x.dynstr = new_dynstr;
 
636
  g_hash_table_foreach  (used_dynamic_symbols,
 
637
                         (GHFunc)output_string,
 
638
                         &x);
 
639
  
 
640
  *size_out = size;
 
641
  return new_dynstr;
 
642
}
 
643
 
 
644
void
 
645
remap_sections(void)
 
646
{
 
647
  Elf32_Shdr *section;
 
648
  Elf32_Word sectionsize;
 
649
  int numsections;
 
650
  int i = 0;
 
651
 
 
652
  section = (Elf32_Shdr *)FILE_OFFSET(read_word(elf_header->e_shoff));
 
653
  sectionsize = read_half(elf_header->e_shentsize);
 
654
  numsections = read_half(elf_header->e_shnum);
 
655
 
 
656
  for (i=0;i<numsections;i++) {
 
657
    write_word(&section->sh_size,
 
658
               fixup_size(read_word(section->sh_offset),
 
659
                          read_word(section->sh_size)));
 
660
    write_word(&section->sh_offset,
 
661
               fixup_offset(read_word(section->sh_offset)));
 
662
    write_word(&section->sh_addr,
 
663
               fixup_addr(read_word(section->sh_addr)));
 
664
    
 
665
    section = (Elf32_Shdr *)((char *)section + sectionsize);
 
666
  }
 
667
}
 
668
 
 
669
 
 
670
void
 
671
remap_segments(void)
 
672
{
 
673
  Elf32_Phdr *segment;
 
674
  Elf32_Word segmentsize;
 
675
  Elf32_Word p_align;
 
676
  int numsegments;
 
677
  int i = 0;
 
678
 
 
679
  segment = (Elf32_Phdr *)FILE_OFFSET(read_word(elf_header->e_phoff));
 
680
  segmentsize = read_half(elf_header->e_phentsize);
 
681
  numsegments = read_half(elf_header->e_phnum);
 
682
 
 
683
  for (i=0;i<numsegments;i++) {
 
684
    write_word(&segment->p_filesz,
 
685
               fixup_size(read_word(segment->p_offset),
 
686
                          read_word(segment->p_filesz)));
 
687
    write_word(&segment->p_offset,
 
688
               fixup_offset(read_word(segment->p_offset)));
 
689
 
 
690
    write_word(&segment->p_memsz,
 
691
               fixup_addr_size(read_word(segment->p_vaddr),
 
692
                               read_word(segment->p_memsz)));
 
693
    write_word(&segment->p_vaddr,
 
694
               fixup_addr(read_word(segment->p_vaddr)));
 
695
    write_word(&segment->p_paddr,
 
696
               read_word(segment->p_vaddr));
 
697
 
 
698
    /* Consistancy checking: */
 
699
    p_align = read_word(segment->p_align);
 
700
    if (p_align > 1) {
 
701
      if ((read_word(segment->p_vaddr) - read_word(segment->p_offset))%p_align != 0) {
 
702
        fprintf(stderr, "Warning, creating non-aligned segment addr: %x offset: %x allign: %x\n",
 
703
                read_word(segment->p_vaddr), read_word(segment->p_offset), p_align);
 
704
      }
 
705
    }
 
706
    
 
707
    segment = (Elf32_Phdr *)((char *)segment + segmentsize);
 
708
  }
 
709
}
 
710
 
 
711
void
 
712
remap_elf_header(void)
 
713
{
 
714
  write_word(&elf_header->e_phoff,
 
715
             fixup_offset(read_word(elf_header->e_phoff)));
 
716
  write_word(&elf_header->e_shoff,
 
717
             fixup_offset(read_word(elf_header->e_shoff)));
 
718
 
 
719
  write_word(&elf_header->e_entry,
 
720
             fixup_addr(read_word(elf_header->e_entry)));
 
721
}
 
722
 
 
723
void
 
724
remap_symtab(Elf32_Shdr *symtab)
 
725
{
 
726
  Elf32_Sym *symbol;
 
727
  Elf32_Sym *symbol_end;
 
728
  Elf32_Word entry_size;
 
729
 
 
730
  symbol = (Elf32_Sym *)FILE_OFFSET(read_word(symtab->sh_offset));
 
731
  symbol_end = (Elf32_Sym *)FILE_OFFSET(read_word(symtab->sh_offset) +
 
732
                                        read_word(symtab->sh_size));
 
733
  entry_size = read_word(symtab->sh_entsize);
 
734
 
 
735
  while (symbol < symbol_end) {
 
736
    write_word(&symbol->st_value,
 
737
               fixup_addr(read_word(symbol->st_value)));
 
738
    symbol = (Elf32_Sym *)((char *)symbol + entry_size);
 
739
  }
 
740
}
 
741
 
 
742
 
 
743
/* Ugly global variables: */
 
744
Elf32_Addr got_data_start = 0;
 
745
Elf32_Addr got_data_end = 0;
 
746
 
 
747
 
 
748
void
 
749
remap_rel_section(Elf32_Rel *rel, Elf32_Word size, Elf32_Word entry_size)
 
750
{
 
751
  Elf32_Rel *rel_end;
 
752
  Elf32_Word offset;
 
753
  Elf32_Addr *addr;
 
754
  Elf32_Word type;
 
755
 
 
756
  rel_end = (Elf32_Rel *)((char *)rel + size);
 
757
 
 
758
  while (rel < rel_end) {
 
759
    type = ELF32_R_TYPE(read_word(rel->r_info)); 
 
760
    switch (machine_type) {
 
761
    case EM_386:
 
762
      if ((type == R_386_RELATIVE) || (type == R_386_JMP_SLOT)) {
 
763
        /* We need to relocate the data this is pointing to too. */
 
764
        offset = vma_to_offset(read_word(rel->r_offset));
 
765
        
 
766
        addr =  (Elf32_Addr *)FILE_OFFSET(offset);
 
767
        write_word(addr, 
 
768
                   fixup_addr(read_word(*addr)));
 
769
      }
 
770
      write_word(&rel->r_offset,
 
771
                 fixup_addr(read_word(rel->r_offset)));
 
772
      break;
 
773
    case EM_PPC:
 
774
      /* The PPC always uses RELA relocations */
 
775
      break;
 
776
    }
 
777
 
 
778
    
 
779
    rel = (Elf32_Rel *)((char *)rel + entry_size);
 
780
  }
 
781
}
 
782
 
 
783
void
 
784
remap_rela_section(Elf32_Rela *rela, Elf32_Word size, Elf32_Word entry_size)
 
785
{
 
786
  Elf32_Rela *rela_end;
 
787
  Elf32_Addr *addr;
 
788
  Elf32_Word offset;
 
789
  Elf32_Word type;
 
790
  Elf32_Word bitmask;
 
791
 
 
792
  rela_end = (Elf32_Rela *)((char *)rela + size);
 
793
 
 
794
  while (rela < rela_end) {
 
795
    type = ELF32_R_TYPE(read_word(rela->r_info));
 
796
    switch (machine_type) {
 
797
    case EM_386:
 
798
      if ((type == R_386_RELATIVE) || (type == R_386_JMP_SLOT)) {
 
799
        /* We need to relocate the data this is pointing to too. */
 
800
        offset = vma_to_offset(read_word(rela->r_offset));
 
801
        
 
802
        addr =  (Elf32_Addr *)FILE_OFFSET(offset);
 
803
        write_word(addr,
 
804
                   fixup_addr(read_word(*addr)));
 
805
      }
 
806
      write_word(&rela->r_offset,
 
807
                 fixup_addr(read_word(rela->r_offset)));
 
808
      break;
 
809
    case EM_PPC:
 
810
/* Some systems do not have PowerPC relocations defined */
 
811
#ifdef R_PPC_NONE
 
812
      switch (type) {
 
813
      case R_PPC_RELATIVE:
 
814
        write_word((Elf32_Word *)&rela->r_addend,
 
815
                   fixup_addr(read_word(rela->r_addend)));
 
816
        /* Fall through for 32bit offset fixup */
 
817
      case R_PPC_ADDR32:
 
818
      case R_PPC_GLOB_DAT:
 
819
      case R_PPC_JMP_SLOT:
 
820
        write_word(&rela->r_offset,
 
821
                   fixup_addr(read_word(rela->r_offset)));
 
822
        break;
 
823
      case R_PPC_NONE:
 
824
        break;
 
825
      default:
 
826
        fprintf(stderr, "Warning, unhandled PPC relocation type %d\n", type);
 
827
      }
 
828
#endif
 
829
      break;
 
830
    }
 
831
    
 
832
    rela = (Elf32_Rela *)((char *)rela + entry_size);
 
833
  }
 
834
}
 
835
 
 
836
void 
 
837
remap_i386_got(void)
 
838
{
 
839
  Elf32_Shdr *got_section;
 
840
  Elf32_Addr *got;
 
841
  Elf32_Addr *got_end;
 
842
  Elf32_Word entry_size;
 
843
 
 
844
  got_section = elf_find_section_named(".got");
 
845
  if (got_section == NULL) {
 
846
    fprintf(stderr, "Warning, no .got section\n");
 
847
    return;
 
848
  }
 
849
 
 
850
  got_data_start = read_word(got_section->sh_offset);
 
851
  got_data_end = got_data_start + read_word(got_section->sh_size);
 
852
  
 
853
  got = (Elf32_Addr *)FILE_OFFSET(got_data_start);
 
854
  got_end = (Elf32_Addr *)FILE_OFFSET(got_data_end);
 
855
  entry_size = read_word(got_section->sh_entsize);
 
856
 
 
857
  write_word(got,
 
858
             fixup_addr(read_word(*got))); /* Pointer to .dynamic */
 
859
}
 
860
 
 
861
void 
 
862
remap_ppc_got(void)
 
863
{
 
864
  Elf32_Shdr *got_section;
 
865
  Elf32_Addr *got;
 
866
  Elf32_Addr *got_end;
 
867
  Elf32_Word entry_size;
 
868
 
 
869
  got_section = elf_find_section_named(".got");
 
870
  if (got_section == NULL) {
 
871
    fprintf(stderr, "Warning, no .got section\n");
 
872
    return;
 
873
  }
 
874
 
 
875
  got_data_start = read_word(got_section->sh_offset);
 
876
  got_data_end = got_data_start + read_word(got_section->sh_size);
 
877
  
 
878
  got = (Elf32_Addr *)FILE_OFFSET(got_data_start);
 
879
  got_end = (Elf32_Addr *)FILE_OFFSET(got_data_end);
 
880
  entry_size = read_word(got_section->sh_entsize);
 
881
 
 
882
  /* Skip reserved part.
 
883
   * Note that this should really be found by finding the
 
884
   * _GLOBAL_OFFSET_TABLE symbol, as it could (according to
 
885
   * the spec) point to the middle of the got.
 
886
   */
 
887
  got = (Elf32_Addr *)((char *)got + entry_size); /* Skip blrl instruction */
 
888
  write_word(got,
 
889
             fixup_addr(read_word(*got))); /* Pointer to .dynamic */
 
890
}
 
891
 
 
892
 
 
893
Elf32_Word
 
894
get_dynamic_val(Elf32_Shdr *dynamic, Elf32_Sword tag)
 
895
{
 
896
  Elf32_Dyn *element;
 
897
  Elf32_Word entry_size;
 
898
 
 
899
  entry_size = read_word(dynamic->sh_entsize);
 
900
 
 
901
  element = (Elf32_Dyn *)FILE_OFFSET(read_word(dynamic->sh_offset));
 
902
  while (read_sword(element->d_tag) != DT_NULL) {
 
903
    if (read_sword(element->d_tag) == tag) {
 
904
      return read_word(element->d_un.d_val);
 
905
    }
 
906
    element = (Elf32_Dyn *)((char *)element + entry_size);
 
907
  }
 
908
  return 0;
 
909
}
 
910
 
 
911
void
 
912
remap_dynamic(Elf32_Shdr *dynamic, Elf32_Word new_dynstr_size)
 
913
{
 
914
  Elf32_Dyn *element;
 
915
  Elf32_Word entry_size;
 
916
  Elf32_Word rel_size;
 
917
  Elf32_Word rel_entry_size;
 
918
  Elf32_Rel *rel;
 
919
  Elf32_Rela *rela;
 
920
  int jmprel_overlaps;
 
921
  Elf32_Word rel_start, rel_end, jmprel_start, jmprel_end;
 
922
    
 
923
  entry_size = read_word(dynamic->sh_entsize);
 
924
 
 
925
  /* Find out if REL/RELA and JMPREL overlaps: */
 
926
  if (get_dynamic_val(dynamic, DT_PLTREL) == DT_REL) {
 
927
    rel_start = get_dynamic_val(dynamic, DT_REL);
 
928
    rel_end = rel_start + get_dynamic_val(dynamic, DT_RELSZ);
 
929
  } else {
 
930
    rel_start = get_dynamic_val(dynamic, DT_RELA);
 
931
    rel_end = rel_start + get_dynamic_val(dynamic, DT_RELASZ);
 
932
  }
 
933
  jmprel_start = get_dynamic_val(dynamic, DT_JMPREL);
 
934
  
 
935
  jmprel_overlaps = 0;
 
936
  if ((jmprel_start >= rel_start) && (jmprel_start < rel_end))
 
937
    jmprel_overlaps = 1;
 
938
    
 
939
  element = (Elf32_Dyn *)FILE_OFFSET(read_word(dynamic->sh_offset));
 
940
  while (read_sword(element->d_tag) != DT_NULL) {
 
941
    switch(read_sword(element->d_tag)) {
 
942
    case DT_STRSZ:
 
943
      write_word(&element->d_un.d_val, new_dynstr_size);
 
944
      break;
 
945
    case DT_PLTGOT:
 
946
    case DT_HASH:
 
947
    case DT_STRTAB:
 
948
    case DT_INIT:
 
949
    case DT_FINI:
 
950
    case DT_VERDEF:
 
951
    case DT_VERNEED:
 
952
    case DT_VERSYM:
 
953
      write_word(&element->d_un.d_ptr,
 
954
                 fixup_addr(read_word(element->d_un.d_ptr)));
 
955
      break;
 
956
    case DT_JMPREL:
 
957
      rel_size = get_dynamic_val(dynamic, DT_PLTRELSZ);
 
958
      if (!jmprel_overlaps) {
 
959
        if (get_dynamic_val(dynamic, DT_PLTREL) == DT_REL) {
 
960
          rel_entry_size = get_dynamic_val(dynamic, DT_RELENT);
 
961
          rel = (Elf32_Rel *)FILE_OFFSET(vma_to_offset(read_word(element->d_un.d_ptr)));
 
962
          remap_rel_section(rel, rel_size, rel_entry_size);
 
963
        } else {
 
964
          rel_entry_size = get_dynamic_val(dynamic, DT_RELAENT);
 
965
          rela = (Elf32_Rela *)FILE_OFFSET(vma_to_offset(read_word(element->d_un.d_ptr)));
 
966
          remap_rela_section(rela, rel_size, rel_entry_size);
 
967
        }
 
968
      }
 
969
      write_word(&element->d_un.d_ptr,
 
970
                 fixup_addr(read_word(element->d_un.d_ptr)));
 
971
      break;
 
972
    case DT_REL:
 
973
      rel_size = get_dynamic_val(dynamic, DT_RELSZ);
 
974
      rel_entry_size = get_dynamic_val(dynamic, DT_RELENT);
 
975
      rel = (Elf32_Rel *)FILE_OFFSET(vma_to_offset(read_word(element->d_un.d_ptr)));
 
976
      remap_rel_section(rel, rel_size, rel_entry_size);
 
977
 
 
978
      write_word(&element->d_un.d_ptr,
 
979
                 fixup_addr(read_word(element->d_un.d_ptr)));
 
980
      break;
 
981
    case DT_RELA:
 
982
      rel_size = get_dynamic_val(dynamic, DT_RELASZ);
 
983
      rel_entry_size = get_dynamic_val(dynamic, DT_RELAENT);
 
984
      rela = (Elf32_Rela *)FILE_OFFSET(vma_to_offset(read_word(element->d_un.d_ptr)));
 
985
      remap_rela_section(rela, rel_size, rel_entry_size);
 
986
 
 
987
      write_word(&element->d_un.d_ptr,
 
988
                 fixup_addr(read_word(element->d_un.d_ptr)));
 
989
      break;
 
990
    default:
 
991
      /*printf("unhandled d_tag: %d (0x%x)\n", read_sword(element->d_tag), read_sword(element->d_tag));*/
 
992
      break;
 
993
    }
 
994
 
 
995
    element = (Elf32_Dyn *)((char *)element + entry_size);
 
996
  }
 
997
}
 
998
 
 
999
void
 
1000
align_hole(Elf32_Word *start, Elf32_Word *end)
 
1001
{
 
1002
  Elf32_Word len;
 
1003
  Elf32_Word align;
 
1004
  Elf32_Shdr *section;
 
1005
  Elf32_Word sectionsize;
 
1006
  int numsections;
 
1007
  int i = 0;
 
1008
  int unaligned;
 
1009
  
 
1010
  len = *end - *start;
 
1011
  align = 0;
 
1012
    
 
1013
  sectionsize = read_half(elf_header->e_shentsize);
 
1014
  numsections = read_half(elf_header->e_shnum);
 
1015
  do {
 
1016
    section = (Elf32_Shdr *)FILE_OFFSET(read_word(elf_header->e_shoff));
 
1017
    unaligned = 0;
 
1018
    
 
1019
    for (i=0;i<numsections;i++) {
 
1020
      if ( (read_word(section->sh_addralign) > 1) &&
 
1021
           ( (read_word(section->sh_offset) - len + align)%read_word(section->sh_addralign) != 0) ) {
 
1022
        unaligned = 1;
 
1023
      }
 
1024
      
 
1025
      section = (Elf32_Shdr *)((char *)section + sectionsize);
 
1026
    }
 
1027
 
 
1028
    if (unaligned) {
 
1029
      align++;
 
1030
    }
 
1031
      
 
1032
  } while (unaligned);
 
1033
 
 
1034
  *start += align;
 
1035
}
 
1036
 
 
1037
int
 
1038
main(int argc, char *argv[])
 
1039
{
 
1040
  int fd;
 
1041
  unsigned char *mapping;
 
1042
  Elf32_Word size;
 
1043
  struct stat statbuf;
 
1044
  Elf32_Shdr *dynamic;
 
1045
  Elf32_Shdr *dynsym;
 
1046
  Elf32_Shdr *symtab;
 
1047
  Elf32_Shdr *dynstr;
 
1048
  Elf32_Shdr *hash;
 
1049
  Elf32_Shdr *higher_section;
 
1050
  Elf32_Word dynstr_index;
 
1051
  Elf32_Shdr *ver_r;
 
1052
  Elf32_Shdr *ver_d;
 
1053
  char *dynstr_data;
 
1054
  unsigned char *new_dynstr;
 
1055
  Elf32_Word old_dynstr_size;
 
1056
  Elf32_Word new_dynstr_size;
 
1057
  
 
1058
  if (argc != 2) {
 
1059
    fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
 
1060
    return 1;
 
1061
  }
 
1062
 
 
1063
  fd = open(argv[1], O_RDWR);
 
1064
  if (fd == -1) {
 
1065
    fprintf(stderr, "Cannot open file %s\n", argv[1]);
 
1066
    return 1;
 
1067
  }
 
1068
  
 
1069
  if (fstat(fd, &statbuf) == -1) {
 
1070
    fprintf(stderr, "Cannot stat file %s\n", argv[1]);
 
1071
    return 1;
 
1072
  }
 
1073
  
 
1074
  size = statbuf.st_size;
 
1075
    
 
1076
  mapping = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 
1077
 
 
1078
  if (mapping == (unsigned char *)-1) {
 
1079
    fprintf(stderr, "Cannot mmap file %s\n", argv[1]);
 
1080
    return 1;
 
1081
  }
 
1082
 
 
1083
  used_dynamic_symbols = g_hash_table_new(g_direct_hash, g_direct_equal);
 
1084
 
 
1085
  elf_header = (Elf32_Ehdr *)mapping;
 
1086
 
 
1087
  if (strncmp((void *)elf_header, ELFMAG, SELFMAG)!=0) {
 
1088
    fprintf(stderr, "Not an ELF file\n");
 
1089
    return 1;
 
1090
  }
 
1091
 
 
1092
  if (elf_header->e_ident[EI_VERSION] != EV_CURRENT) {
 
1093
    fprintf(stderr, "Wrong ELF file version\n");
 
1094
    return 1;
 
1095
  }
 
1096
 
 
1097
  if (elf_header->e_ident[EI_CLASS] != ELFCLASS32) {
 
1098
    fprintf(stderr, "Only 32bit ELF files supported\n");
 
1099
    return 1;
 
1100
  }
 
1101
  
 
1102
  setup_byteswapping(elf_header->e_ident[EI_DATA]);
 
1103
 
 
1104
  machine_type = read_half(elf_header->e_machine);
 
1105
  if ( (machine_type != EM_386) &&
 
1106
       (machine_type != EM_PPC) ) {
 
1107
    fprintf(stderr, "Unsupported architecture. Supported are: x86, ppc\n");
 
1108
    return 1;
 
1109
  }
 
1110
 
 
1111
  if (read_half(elf_header->e_type) != ET_DYN) {
 
1112
    fprintf(stderr, "Not an ELF shared object\n");
 
1113
    return 1;
 
1114
  }
 
1115
  
 
1116
  dynamic = elf_find_section(SHT_DYNAMIC);
 
1117
  dynsym = elf_find_section(SHT_DYNSYM);
 
1118
  symtab = elf_find_section(SHT_SYMTAB);
 
1119
  dynstr_index = read_word(dynsym->sh_link);
 
1120
  dynstr = elf_find_section_num(dynstr_index);
 
1121
  dynstr_data = (char *)FILE_OFFSET(read_word(dynstr->sh_offset));
 
1122
  old_dynstr_size = read_word(dynstr->sh_size);
 
1123
  ver_d = elf_find_section(SHT_GNU_verdef);
 
1124
  ver_r = elf_find_section(SHT_GNU_verneed);
 
1125
  hash = elf_find_section(SHT_HASH);
 
1126
 
 
1127
  /* Generate hash table with all used strings: */
 
1128
  
 
1129
  add_strings_from_dynsym(dynsym, dynstr_data);
 
1130
  add_strings_from_dynamic(dynamic, dynstr_data);
 
1131
  if (ver_d && (read_word(ver_d->sh_link) == dynstr_index))
 
1132
    add_strings_from_ver_d(ver_d, dynstr_data);
 
1133
  if (ver_r && (read_word(ver_r->sh_link) == dynstr_index))
 
1134
    add_strings_from_ver_r(ver_r, dynstr_data);
 
1135
 
 
1136
  /* Generate new dynstr section from the used strings hashtable: */
 
1137
  
 
1138
  new_dynstr = generate_new_dynstr(&new_dynstr_size);
 
1139
  /*
 
1140
  printf("New dynstr size: %d\n", new_dynstr_size);
 
1141
  printf("Old dynstr size: %d\n", old_dynstr_size);
 
1142
  */
 
1143
  
 
1144
  if (new_dynstr_size >= old_dynstr_size) {
 
1145
    return 0;
 
1146
  }
 
1147
 
 
1148
  /* Fixup all references: */
 
1149
  fixup_strings_in_dynsym(dynsym);
 
1150
  fixup_strings_in_dynamic(dynamic);
 
1151
  if (ver_d && (read_word(ver_d->sh_link) == dynstr_index))
 
1152
    fixup_strings_in_ver_d(ver_d);
 
1153
  if (ver_r && (read_word(ver_r->sh_link) == dynstr_index))
 
1154
    fixup_strings_in_ver_r(ver_r);
 
1155
  
 
1156
  /* Copy over the new dynstr: */
 
1157
  memcpy(dynstr_data, new_dynstr, new_dynstr_size);
 
1158
  memset(dynstr_data + new_dynstr_size, ' ', old_dynstr_size-new_dynstr_size);
 
1159
 
 
1160
  /* Compact the dynstr section and the file: */
 
1161
 
 
1162
  /* 1. Set up the data for the fixup_offset() function: */
 
1163
  hole_index = read_word(dynstr->sh_offset) + new_dynstr_size;
 
1164
  higher_section = elf_find_next_higher_section(hole_index);
 
1165
  hole_end = read_word(higher_section->sh_offset);
 
1166
 
 
1167
  align_hole(&hole_index, &hole_end);
 
1168
  hole_len = hole_end - hole_index;
 
1169
 
 
1170
  hole_addr_start = hole_index; /* TODO: Fix this to something better */
 
1171
 
 
1172
  find_segment_addr_min_max(read_word(dynstr->sh_offset),
 
1173
                            &hole_addr_remap_start, &hole_addr_remap_end);
 
1174
  
 
1175
  /*
 
1176
  printf("Hole remap: 0x%lx - 0x%lx\n", hole_addr_remap_start, hole_addr_remap_end);
 
1177
 
 
1178
  printf("hole: %lu - %lu (%lu bytes)\n", hole_index, hole_end, hole_len);
 
1179
  printf("hole: 0x%lx - 0x%lx (0x%lx bytes)\n", hole_index, hole_end, hole_len);
 
1180
  */
 
1181
  
 
1182
  /* 2. Change all section and segment sizes and offsets: */
 
1183
  remap_symtab(dynsym);
 
1184
  if (symtab)
 
1185
    remap_symtab(symtab);
 
1186
 
 
1187
  if (machine_type == EM_386)
 
1188
    remap_i386_got();
 
1189
  if (machine_type == EM_PPC)
 
1190
    remap_ppc_got();
 
1191
  
 
1192
  remap_dynamic(dynamic, new_dynstr_size);
 
1193
  remap_sections(); /* After this line the section headers are wrong */
 
1194
  remap_segments();
 
1195
  remap_elf_header();
 
1196
    
 
1197
  /* 3. Do the real compacting. */
 
1198
 
 
1199
  memmove(mapping + hole_index,
 
1200
          mapping + hole_index + hole_len,
 
1201
          size - (hole_index + hole_len));
 
1202
  
 
1203
  munmap(mapping, size);
 
1204
 
 
1205
  ftruncate(fd, size - hole_len);
 
1206
  close(fd);
 
1207
 
 
1208
  return 0;
 
1209
}
 
1210
 
 
1211
 
 
1212