|
Lines 27-32
Link Here
|
| 27 |
#include "reloc.h" |
27 |
#include "reloc.h" |
| 28 |
#include "space.h" |
28 |
#include "space.h" |
| 29 |
|
29 |
|
|
|
30 |
#define goto_error_out \ |
| 31 |
{ \ |
| 32 |
free (liblist); \ |
| 33 |
free (move); \ |
| 34 |
return 1; \ |
| 35 |
} |
| 36 |
|
| 30 |
int |
37 |
int |
| 31 |
update_dynamic_tags (DSO *dso, GElf_Shdr *shdr, GElf_Shdr *old_shdr, |
38 |
update_dynamic_tags (DSO *dso, GElf_Shdr *shdr, GElf_Shdr *old_shdr, |
| 32 |
struct section_move *move) |
39 |
struct section_move *move) |
|
Lines 116-128
Link Here
|
| 116 |
Elf_Data *data; |
123 |
Elf_Data *data; |
| 117 |
|
124 |
|
| 118 |
if (undo_sections (dso, undo, move, &rinfo, &ehdr, phdr, shdr)) |
125 |
if (undo_sections (dso, undo, move, &rinfo, &ehdr, phdr, shdr)) |
| 119 |
{ |
126 |
goto_error_out |
| 120 |
error_out: |
|
|
| 121 |
free (liblist); |
| 122 |
free (move); |
| 123 |
return 1; |
| 124 |
} |
| 125 |
|
| 126 |
data = elf_getdata (dso->scn[undo], NULL); |
127 |
data = elf_getdata (dso->scn[undo], NULL); |
| 127 |
assert (data->d_buf != NULL); |
128 |
assert (data->d_buf != NULL); |
| 128 |
assert (data->d_off == 0); |
129 |
assert (data->d_off == 0); |
|
Lines 133-139
Link Here
|
| 133 |
{ |
134 |
{ |
| 134 |
error (0, ENOMEM, "%s: Could not create .gnu.prelink_undo section", |
135 |
error (0, ENOMEM, "%s: Could not create .gnu.prelink_undo section", |
| 135 |
dso->filename); |
136 |
dso->filename); |
| 136 |
goto error_out; |
137 |
goto_error_out |
| 137 |
} |
138 |
} |
| 138 |
memcpy (dso->undo.d_buf, data->d_buf, data->d_size); |
139 |
memcpy (dso->undo.d_buf, data->d_buf, data->d_size); |
| 139 |
ehdr.e_shstrndx = dso->ehdr.e_shstrndx; |
140 |
ehdr.e_shstrndx = dso->ehdr.e_shstrndx; |
|
Lines 151-157
Link Here
|
| 151 |
if (dynstrndx == dso->ehdr.e_shnum) |
152 |
if (dynstrndx == dso->ehdr.e_shnum) |
| 152 |
{ |
153 |
{ |
| 153 |
error (0, 0, "%s: Could not find .dynstr section", dso->filename); |
154 |
error (0, 0, "%s: Could not find .dynstr section", dso->filename); |
| 154 |
goto error_out; |
155 |
goto_error_out |
| 155 |
} |
156 |
} |
| 156 |
|
157 |
|
| 157 |
dynstrndxnew = move->old_to_new[dynstrndx]; |
158 |
dynstrndxnew = move->old_to_new[dynstrndx]; |
|
Lines 165-171
Link Here
|
| 165 |
{ |
166 |
{ |
| 166 |
error (0, ENOMEM, "%s: Cannot build .gnu.liblist section", |
167 |
error (0, ENOMEM, "%s: Cannot build .gnu.liblist section", |
| 167 |
dso->filename); |
168 |
dso->filename); |
| 168 |
goto error_out; |
169 |
goto_error_out |
| 169 |
} |
170 |
} |
| 170 |
} |
171 |
} |
| 171 |
else |
172 |
else |
|
Lines 348-354
Link Here
|
| 348 |
{ |
349 |
{ |
| 349 |
new[i] = find_readonly_space (dso, add + i, &ehdr, phdr, shdr, &adjust); |
350 |
new[i] = find_readonly_space (dso, add + i, &ehdr, phdr, shdr, &adjust); |
| 350 |
if (new[i] == 0) |
351 |
if (new[i] == 0) |
| 351 |
goto error_out; |
352 |
goto_error_out |
| 352 |
add_section (move, new[i]); |
353 |
add_section (move, new[i]); |
| 353 |
++adjust.newcount; |
354 |
++adjust.newcount; |
| 354 |
if (old[i]) |
355 |
if (old[i]) |
|
Lines 435-441
Link Here
|
| 435 |
dso->ehdr = ehdr; |
436 |
dso->ehdr = ehdr; |
| 436 |
memcpy (dso->phdr, phdr, ehdr.e_phnum * sizeof (GElf_Phdr)); |
437 |
memcpy (dso->phdr, phdr, ehdr.e_phnum * sizeof (GElf_Phdr)); |
| 437 |
if (reopen_dso (dso, move, NULL)) |
438 |
if (reopen_dso (dso, move, NULL)) |
| 438 |
goto error_out; |
439 |
goto_error_out |
| 439 |
|
440 |
|
| 440 |
assert (i == dso->ehdr.e_shnum); |
441 |
assert (i == dso->ehdr.e_shnum); |
| 441 |
|
442 |
|
|
Lines 477-483
Link Here
|
| 477 |
{ |
478 |
{ |
| 478 |
error (0, ENOMEM, "%s: Could not convert NOBITS section into PROGBITS", |
479 |
error (0, ENOMEM, "%s: Could not convert NOBITS section into PROGBITS", |
| 479 |
dso->filename); |
480 |
dso->filename); |
| 480 |
goto error_out; |
481 |
goto_error_out |
| 481 |
} |
482 |
} |
| 482 |
} |
483 |
} |
| 483 |
data->d_type = ELF_T_BYTE; |
484 |
data->d_type = ELF_T_BYTE; |
|
Lines 506-512
Link Here
|
| 506 |
{ |
507 |
{ |
| 507 |
error (0, 0, "%s: NOBITS section followed by non-NOBITS section in the same segment", |
508 |
error (0, 0, "%s: NOBITS section followed by non-NOBITS section in the same segment", |
| 508 |
dso->filename); |
509 |
dso->filename); |
| 509 |
goto error_out; |
510 |
goto_error_out |
| 510 |
} |
511 |
} |
| 511 |
continue; |
512 |
continue; |
| 512 |
} |
513 |
} |
|
Lines 536-542
Link Here
|
| 536 |
{ |
537 |
{ |
| 537 |
error (0, ENOMEM, "%s: Could not convert NOBITS section into PROGBITS", |
538 |
error (0, ENOMEM, "%s: Could not convert NOBITS section into PROGBITS", |
| 538 |
dso->filename); |
539 |
dso->filename); |
| 539 |
goto error_out; |
540 |
goto_error_out |
| 540 |
} |
541 |
} |
| 541 |
} |
542 |
} |
| 542 |
memset (data->d_buf, 0, data->d_size); |
543 |
memset (data->d_buf, 0, data->d_size); |
|
Lines 587-593
Link Here
|
| 587 |
{ |
588 |
{ |
| 588 |
error (0, 0, "%s: section spans beyond end of segment", |
589 |
error (0, 0, "%s: section spans beyond end of segment", |
| 589 |
dso->filename); |
590 |
dso->filename); |
| 590 |
goto error_out; |
591 |
goto_error_out |
| 591 |
} |
592 |
} |
| 592 |
else |
593 |
else |
| 593 |
{ |
594 |
{ |
|
Lines 621-627
Link Here
|
| 621 |
if (adjust_dso_nonalloc (dso, last + 1, |
622 |
if (adjust_dso_nonalloc (dso, last + 1, |
| 622 |
dso->shdr[sfirst].sh_offset, |
623 |
dso->shdr[sfirst].sh_offset, |
| 623 |
adj)) |
624 |
adj)) |
| 624 |
goto error_out; |
625 |
goto_error_out |
| 625 |
} |
626 |
} |
| 626 |
} |
627 |
} |
| 627 |
|
628 |
|
|
Lines 644-650
Link Here
|
| 644 |
dso->shdr[j].sh_size |
645 |
dso->shdr[j].sh_size |
| 645 |
= dso->shdr[j].sh_size / 3 * 2; |
646 |
= dso->shdr[j].sh_size / 3 * 2; |
| 646 |
if (convert_rel_to_rela (dso, j)) |
647 |
if (convert_rel_to_rela (dso, j)) |
| 647 |
goto error_out; |
648 |
goto_error_out |
| 648 |
dso->shdr[j].sh_size = shdr[j].sh_size; |
649 |
dso->shdr[j].sh_size = shdr[j].sh_size; |
| 649 |
} |
650 |
} |
| 650 |
} |
651 |
} |
|
Lines 671-677
Link Here
|
| 671 |
dso->shdr[rinfo.first].sh_size |
672 |
dso->shdr[rinfo.first].sh_size |
| 672 |
= dso->shdr[rinfo.first].sh_size / 3 * 2; |
673 |
= dso->shdr[rinfo.first].sh_size / 3 * 2; |
| 673 |
if (convert_rel_to_rela (dso, rinfo.plt)) |
674 |
if (convert_rel_to_rela (dso, rinfo.plt)) |
| 674 |
goto error_out; |
675 |
goto_error_out |
| 675 |
dso->shdr[rinfo.plt].sh_size = shdr[rinfo.plt].sh_size; |
676 |
dso->shdr[rinfo.plt].sh_size = shdr[rinfo.plt].sh_size; |
| 676 |
} |
677 |
} |
| 677 |
else if (rinfonew.rel_to_rela_plt) |
678 |
else if (rinfonew.rel_to_rela_plt) |
|
Lines 696-702
Link Here
|
| 696 |
{ |
697 |
{ |
| 697 |
error (0, ENOMEM, "%s: Could not append names needed for .gnu.liblist to .dynstr", |
698 |
error (0, ENOMEM, "%s: Could not append names needed for .gnu.liblist to .dynstr", |
| 698 |
dso->filename); |
699 |
dso->filename); |
| 699 |
goto error_out; |
700 |
goto_error_out |
| 700 |
} |
701 |
} |
| 701 |
ptr = data->d_buf + shdr_after_undo[dynstrndxnew].sh_size; |
702 |
ptr = data->d_buf + shdr_after_undo[dynstrndxnew].sh_size; |
| 702 |
data->d_size = dso->shdr[i].sh_size; |
703 |
data->d_size = dso->shdr[i].sh_size; |
|
Lines 720-726
Link Here
|
| 720 |
|
721 |
|
| 721 |
dso->shdr[new_sdynbss].sh_name = shstrtabadd (dso, ".sdynbss"); |
722 |
dso->shdr[new_sdynbss].sh_name = shstrtabadd (dso, ".sdynbss"); |
| 722 |
if (dso->shdr[new_sdynbss].sh_name == 0) |
723 |
if (dso->shdr[new_sdynbss].sh_name == 0) |
| 723 |
goto error_out; |
724 |
goto_error_out |
| 724 |
|
725 |
|
| 725 |
dso->shdr[new_sdynbss].sh_size = |
726 |
dso->shdr[new_sdynbss].sh_size = |
| 726 |
info->sdynbss_base + info->sdynbss_size |
727 |
info->sdynbss_base + info->sdynbss_size |
|
Lines 744-750
Link Here
|
| 744 |
{ |
745 |
{ |
| 745 |
error (0, 0, "%s: Copy relocs don't point into .sdynbss section", |
746 |
error (0, 0, "%s: Copy relocs don't point into .sdynbss section", |
| 746 |
dso->filename); |
747 |
dso->filename); |
| 747 |
goto error_out; |
748 |
goto_error_out |
| 748 |
} |
749 |
} |
| 749 |
} |
750 |
} |
| 750 |
data = elf_getdata (dso->scn[new_sdynbss], NULL); |
751 |
data = elf_getdata (dso->scn[new_sdynbss], NULL); |
|
Lines 787-793
Link Here
|
| 787 |
else |
788 |
else |
| 788 |
dso->shdr[new_dynbss].sh_name = shstrtabadd (dso, ".dynbss"); |
789 |
dso->shdr[new_dynbss].sh_name = shstrtabadd (dso, ".dynbss"); |
| 789 |
if (dso->shdr[new_dynbss].sh_name == 0) |
790 |
if (dso->shdr[new_dynbss].sh_name == 0) |
| 790 |
goto error_out; |
791 |
goto_error_out |
| 791 |
|
792 |
|
| 792 |
dso->shdr[new_dynbss].sh_size = |
793 |
dso->shdr[new_dynbss].sh_size = |
| 793 |
info->dynbss_base + info->dynbss_size |
794 |
info->dynbss_base + info->dynbss_size |
|
Lines 821-827
Link Here
|
| 821 |
{ |
822 |
{ |
| 822 |
error (0, 0, "%s: COPY relocs not present at start of first SHT_NOBITS section", |
823 |
error (0, 0, "%s: COPY relocs not present at start of first SHT_NOBITS section", |
| 823 |
dso->filename); |
824 |
dso->filename); |
| 824 |
goto error_out; |
825 |
goto_error_out |
| 825 |
} |
826 |
} |
| 826 |
} |
827 |
} |
| 827 |
|
828 |
|
|
Lines 891-897
Link Here
|
| 891 |
if (adjust_dso_nonalloc (dso, new_dynbss + 2, |
892 |
if (adjust_dso_nonalloc (dso, new_dynbss + 2, |
| 892 |
dso->shdr[new_dynbss].sh_offset, |
893 |
dso->shdr[new_dynbss].sh_offset, |
| 893 |
adj)) |
894 |
adj)) |
| 894 |
goto error_out; |
895 |
goto_error_out |
| 895 |
} |
896 |
} |
| 896 |
} |
897 |
} |
| 897 |
else |
898 |
else |
|
Lines 904-910
Link Here
|
| 904 |
{ |
905 |
{ |
| 905 |
error (0, 0, "%s: Copy relocs don't point into .dynbss section", |
906 |
error (0, 0, "%s: Copy relocs don't point into .dynbss section", |
| 906 |
dso->filename); |
907 |
dso->filename); |
| 907 |
goto error_out; |
908 |
goto_error_out |
| 908 |
} |
909 |
} |
| 909 |
} |
910 |
} |
| 910 |
data = elf_getdata (dso->scn[new_dynbss], NULL); |
911 |
data = elf_getdata (dso->scn[new_dynbss], NULL); |
|
Lines 948-954
Link Here
|
| 948 |
dso->shdr[i].sh_entsize = shdr[i].sh_entsize; |
949 |
dso->shdr[i].sh_entsize = shdr[i].sh_entsize; |
| 949 |
dso->shdr[i].sh_name = shstrtabadd (dso, ".gnu.liblist"); |
950 |
dso->shdr[i].sh_name = shstrtabadd (dso, ".gnu.liblist"); |
| 950 |
if (dso->shdr[i].sh_name == 0) |
951 |
if (dso->shdr[i].sh_name == 0) |
| 951 |
goto error_out; |
952 |
goto_error_out |
| 952 |
else |
953 |
else |
| 953 |
{ |
954 |
{ |
| 954 |
Elf_Data *data; |
955 |
Elf_Data *data; |
|
Lines 965-973
Link Here
|
| 965 |
data->d_align = sizeof (GElf_Word); |
966 |
data->d_align = sizeof (GElf_Word); |
| 966 |
data->d_version = EV_CURRENT; |
967 |
data->d_version = EV_CURRENT; |
| 967 |
if (set_dynamic (dso, DT_GNU_LIBLIST, dso->shdr[i].sh_addr, 1)) |
968 |
if (set_dynamic (dso, DT_GNU_LIBLIST, dso->shdr[i].sh_addr, 1)) |
| 968 |
goto error_out; |
969 |
goto_error_out |
| 969 |
if (set_dynamic (dso, DT_GNU_LIBLISTSZ, dso->shdr[i].sh_size, 1)) |
970 |
if (set_dynamic (dso, DT_GNU_LIBLISTSZ, dso->shdr[i].sh_size, 1)) |
| 970 |
goto error_out; |
971 |
goto_error_out |
| 971 |
} |
972 |
} |
| 972 |
|
973 |
|
| 973 |
/* Create the conflict list if necessary. */ |
974 |
/* Create the conflict list if necessary. */ |
|
Lines 990-996
Link Here
|
| 990 |
{ |
991 |
{ |
| 991 |
error (0, ENOMEM, "%s: Could not build .gnu.conflict section", |
992 |
error (0, ENOMEM, "%s: Could not build .gnu.conflict section", |
| 992 |
dso->filename); |
993 |
dso->filename); |
| 993 |
goto error_out; |
994 |
goto_error_out |
| 994 |
} |
995 |
} |
| 995 |
} |
996 |
} |
| 996 |
else |
997 |
else |
|
Lines 1013-1023
Link Here
|
| 1013 |
dso->shdr[i].sh_link = j; |
1014 |
dso->shdr[i].sh_link = j; |
| 1014 |
dso->shdr[i].sh_name = shstrtabadd (dso, ".gnu.conflict"); |
1015 |
dso->shdr[i].sh_name = shstrtabadd (dso, ".gnu.conflict"); |
| 1015 |
if (dso->shdr[i].sh_name == 0) |
1016 |
if (dso->shdr[i].sh_name == 0) |
| 1016 |
goto error_out; |
1017 |
goto_error_out |
| 1017 |
if (set_dynamic (dso, DT_GNU_CONFLICT, dso->shdr[i].sh_addr, 1)) |
1018 |
if (set_dynamic (dso, DT_GNU_CONFLICT, dso->shdr[i].sh_addr, 1)) |
| 1018 |
goto error_out; |
1019 |
goto_error_out |
| 1019 |
if (set_dynamic (dso, DT_GNU_CONFLICTSZ, dso->shdr[i].sh_size, 1)) |
1020 |
if (set_dynamic (dso, DT_GNU_CONFLICTSZ, dso->shdr[i].sh_size, 1)) |
| 1020 |
goto error_out; |
1021 |
goto_error_out |
| 1021 |
} |
1022 |
} |
| 1022 |
|
1023 |
|
| 1023 |
if (undo != -1) |
1024 |
if (undo != -1) |
|
Lines 1052-1061
Link Here
|
| 1052 |
recompute_nonalloc_offsets (dso); |
1053 |
recompute_nonalloc_offsets (dso); |
| 1053 |
|
1054 |
|
| 1054 |
if (update_dynamic_tags (dso, dso->shdr, old_shdr, move)) |
1055 |
if (update_dynamic_tags (dso, dso->shdr, old_shdr, move)) |
| 1055 |
goto error_out; |
1056 |
goto_error_out |
| 1056 |
|
1057 |
|
| 1057 |
if (update_dynamic_rel (dso, &rinfo)) |
1058 |
if (update_dynamic_rel (dso, &rinfo)) |
| 1058 |
goto error_out; |
1059 |
goto_error_out |
| 1059 |
|
1060 |
|
| 1060 |
free (move); |
1061 |
free (move); |
| 1061 |
return 0; |
1062 |
return 0; |