Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: tools/relocation_packer/src/elf_file.cc

Issue 474283002: Update DT_RELA* fields when packing relocations with addends. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "elf_file.h" 5 #include "elf_file.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <sys/types.h> 8 #include <sys/types.h>
9 #include <unistd.h> 9 #include <unistd.h>
10 #include <string> 10 #include <string>
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag 385 VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag
386 << " d_ptr adjusted to " << dynamic->d_un.d_ptr; 386 << " d_ptr adjusted to " << dynamic->d_un.d_ptr;
387 } 387 }
388 388
389 // If we are specifically resizing dynamic relocations, we need to make 389 // If we are specifically resizing dynamic relocations, we need to make
390 // some added adjustments to tags that indicate the counts of relative 390 // some added adjustments to tags that indicate the counts of relative
391 // relocations in the shared object. 391 // relocations in the shared object.
392 if (!is_relocations_resize) 392 if (!is_relocations_resize)
393 continue; 393 continue;
394 394
395 // DT_RELSZ is the overall size of relocations. Adjust by hole size. 395 // DT_RELSZ or DT_RELASZ indicate the overall size of relocations.
396 if (tag == DT_RELSZ) { 396 // Only one will be present. Adjust by hole size.
rmcilroy 2014/08/15 16:28:47 Should we assert that only one is present?
397 if (tag == DT_RELSZ || tag == DT_RELASZ) {
397 dynamic->d_un.d_val += hole_size; 398 dynamic->d_un.d_val += hole_size;
398 VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag 399 VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag
399 << " d_val adjusted to " << dynamic->d_un.d_val; 400 << " d_val adjusted to " << dynamic->d_un.d_val;
400 } 401 }
401 402
402 // DT_RELCOUNT is the count of relative relocations. Packing reduces it 403 // DT_RELCOUNT or DT_RELACOUNT hold the count of relative relocations.
403 // to the alignment padding, if any; unpacking restores it to its former 404 // Only one will be present. Packing reduces it to the alignment
404 // value. The crazy linker does not use it, but we update it anyway. 405 // padding, if any; unpacking restores it to its former value. The
405 if (tag == DT_RELCOUNT) { 406 // crazy linker does not use it, but we update it anyway.
407 if (tag == DT_RELCOUNT || tag == DT_RELACOUNT) {
406 // Cast sizeof to a signed type to avoid the division result being 408 // Cast sizeof to a signed type to avoid the division result being
407 // promoted into an unsigned size_t. 409 // promoted into an unsigned size_t.
408 const ssize_t sizeof_rel = static_cast<ssize_t>(sizeof(Rel)); 410 const ssize_t sizeof_rel = static_cast<ssize_t>(sizeof(Rel));
409 dynamic->d_un.d_val += hole_size / sizeof_rel; 411 dynamic->d_un.d_val += hole_size / sizeof_rel;
410 VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag 412 VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag
411 << " d_val adjusted to " << dynamic->d_un.d_val; 413 << " d_val adjusted to " << dynamic->d_un.d_val;
412 } 414 }
413 415
414 // DT_RELENT doesn't change, but make sure it is what we expect. 416 // DT_RELENT and DT_RELAENT don't change, but make sure they are what
415 if (tag == DT_RELENT) { 417 // we expect. Only one will be present.
418 if (tag == DT_RELENT || tag == DT_RELAENT) {
416 CHECK(dynamic->d_un.d_val == sizeof(Rel)); 419 CHECK(dynamic->d_un.d_val == sizeof(Rel));
417 } 420 }
418 } 421 }
419 422
420 void* section_data = &dynamics[0]; 423 void* section_data = &dynamics[0];
421 size_t bytes = dynamics.size() * sizeof(dynamics[0]); 424 size_t bytes = dynamics.size() * sizeof(dynamics[0]);
422 RewriteSectionData(data, section_data, bytes); 425 RewriteSectionData(data, section_data, bytes);
423 } 426 }
424 427
425 // Helper for ResizeSection(). Adjust the .dynsym section for the hole. 428 // Helper for ResizeSection(). Adjust the .dynsym section for the hole.
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 // Resize a section. If the new size is larger than the current size, open 515 // Resize a section. If the new size is larger than the current size, open
513 // up a hole by increasing file offsets that come after the hole. If smaller 516 // up a hole by increasing file offsets that come after the hole. If smaller
514 // than the current size, remove the hole by decreasing those offsets. 517 // than the current size, remove the hole by decreasing those offsets.
515 template <typename Rel> 518 template <typename Rel>
516 void ResizeSection(Elf* elf, Elf_Scn* section, size_t new_size) { 519 void ResizeSection(Elf* elf, Elf_Scn* section, size_t new_size) {
517 ELF::Shdr* section_header = ELF::getshdr(section); 520 ELF::Shdr* section_header = ELF::getshdr(section);
518 if (section_header->sh_size == new_size) 521 if (section_header->sh_size == new_size)
519 return; 522 return;
520 523
521 // Note if we are resizing the real dyn relocations. If yes, then we have 524 // Note if we are resizing the real dyn relocations. If yes, then we have
522 // to massage d_un.d_val in the dynamic section where d_tag is DT_RELSZ and 525 // to massage d_un.d_val in the dynamic section where d_tag is DT_RELSZ or
523 // DT_RELCOUNT. 526 // DT_RELASZ and DT_RELCOUNT or DT_RELACOUNT.
524 size_t string_index; 527 size_t string_index;
525 elf_getshdrstrndx(elf, &string_index); 528 elf_getshdrstrndx(elf, &string_index);
526 const std::string section_name = 529 const std::string section_name =
527 elf_strptr(elf, string_index, section_header->sh_name); 530 elf_strptr(elf, string_index, section_header->sh_name);
528 const bool is_relocations_resize = 531 const bool is_relocations_resize =
529 (section_name == ".rel.dyn" || section_name == ".rela.dyn"); 532 (section_name == ".rel.dyn" || section_name == ".rela.dyn");
530 533
531 // Require that the section size and the data size are the same. True 534 // Require that the section size and the data size are the same. True
532 // in practice for all sections we resize when packing or unpacking. 535 // in practice for all sections we resize when packing or unpacking.
533 Elf_Data* data = GetSectionData(section); 536 Elf_Data* data = GetSectionData(section);
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 std::vector<Rel> relative_relocations; 1078 std::vector<Rel> relative_relocations;
1076 RelocationPacker packer; 1079 RelocationPacker packer;
1077 packer.UnpackRelativeRelocations(packed, &relative_relocations); 1080 packer.UnpackRelativeRelocations(packed, &relative_relocations);
1078 const size_t unpacked_bytes = 1081 const size_t unpacked_bytes =
1079 relative_relocations.size() * sizeof(relative_relocations[0]); 1082 relative_relocations.size() * sizeof(relative_relocations[0]);
1080 LOG(INFO) << "Unpacked relative: " << unpacked_bytes << " bytes"; 1083 LOG(INFO) << "Unpacked relative: " << unpacked_bytes << " bytes";
1081 1084
1082 // Retrieve the current dynamic relocations section data. 1085 // Retrieve the current dynamic relocations section data.
1083 data = GetSectionData(relocations_section_); 1086 data = GetSectionData(relocations_section_);
1084 1087
1085 // Interpret data as Elf32 relocations. 1088 // Interpret data as relocations.
1086 const Rel* relocations_base = reinterpret_cast<Rel*>(data->d_buf); 1089 const Rel* relocations_base = reinterpret_cast<Rel*>(data->d_buf);
1087 std::vector<Rel> relocations( 1090 std::vector<Rel> relocations(
1088 relocations_base, 1091 relocations_base,
1089 relocations_base + data->d_size / sizeof(relocations[0])); 1092 relocations_base + data->d_size / sizeof(relocations[0]));
1090 1093
1091 std::vector<Rel> other_relocations; 1094 std::vector<Rel> other_relocations;
1092 size_t padding = 0; 1095 size_t padding = 0;
1093 1096
1094 // Filter relocations to locate any that are NONE-type. These will occur 1097 // Filter relocations to locate any that are NONE-type. These will occur
1095 // if padding was turned on for packing. 1098 // if padding was turned on for packing.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 1189
1187 // Clean up libelf, and truncate the output file to the number of bytes 1190 // Clean up libelf, and truncate the output file to the number of bytes
1188 // written by elf_update(). 1191 // written by elf_update().
1189 elf_end(elf_); 1192 elf_end(elf_);
1190 elf_ = NULL; 1193 elf_ = NULL;
1191 const int truncate = ftruncate(fd_, file_bytes); 1194 const int truncate = ftruncate(fd_, file_bytes);
1192 CHECK(truncate == 0); 1195 CHECK(truncate == 0);
1193 } 1196 }
1194 1197
1195 } // namespace relocation_packer 1198 } // namespace relocation_packer
OLDNEW
« no previous file with comments | « no previous file | tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698