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

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

Issue 650293006: Tidy ELF section rewriting internal interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month 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 | « tools/relocation_packer/src/elf_file.h ('k') | no next file » | 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 // Implementation notes: 5 // Implementation notes:
6 // 6 //
7 // We need to remove a piece from the ELF shared library. However, we also 7 // We need to remove a piece from the ELF shared library. However, we also
8 // want to ensure that code and data loads at the same addresses as before 8 // want to ensure that code and data loads at the same addresses as before
9 // packing, so that tools like breakpad can still match up addresses found 9 // packing, so that tools like breakpad can still match up addresses found
10 // in any crash dumps with data extracted from the pre-packed version of 10 // in any crash dumps with data extracted from the pre-packed version of
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 // by ensuring that a call to elf_getdata(section, data) returns NULL as 64 // by ensuring that a call to elf_getdata(section, data) returns NULL as
65 // the next data entry. 65 // the next data entry.
66 Elf_Data* GetSectionData(Elf_Scn* section) { 66 Elf_Data* GetSectionData(Elf_Scn* section) {
67 Elf_Data* data = elf_getdata(section, NULL); 67 Elf_Data* data = elf_getdata(section, NULL);
68 CHECK(data && elf_getdata(section, data) == NULL); 68 CHECK(data && elf_getdata(section, data) == NULL);
69 return data; 69 return data;
70 } 70 }
71 71
72 // Rewrite section data. Allocates new data and makes it the data element's 72 // Rewrite section data. Allocates new data and makes it the data element's
73 // buffer. Relies on program exit to free allocated data. 73 // buffer. Relies on program exit to free allocated data.
74 void RewriteSectionData(Elf_Data* data, 74 void RewriteSectionData(Elf_Scn* section,
75 const void* section_data, 75 const void* section_data,
76 size_t size) { 76 size_t size) {
77 Elf_Data* data = GetSectionData(section);
77 CHECK(size == data->d_size); 78 CHECK(size == data->d_size);
78 uint8_t* area = new uint8_t[size]; 79 uint8_t* area = new uint8_t[size];
79 memcpy(area, section_data, size); 80 memcpy(area, section_data, size);
80 data->d_buf = area; 81 data->d_buf = area;
81 } 82 }
82 83
83 // Verbose ELF header logging. 84 // Verbose ELF header logging.
84 void VerboseLogElfHeader(const ELF::Ehdr* elf_header) { 85 void VerboseLogElfHeader(const ELF::Ehdr* elf_header) {
85 VLOG(1) << "e_phoff = " << elf_header->e_phoff; 86 VLOG(1) << "e_phoff = " << elf_header->e_phoff;
86 VLOG(1) << "e_shoff = " << elf_header->e_shoff; 87 VLOG(1) << "e_shoff = " << elf_header->e_shoff;
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 791
791 // DT_RELENT and DT_RELAENT do not change, but make sure they are what 792 // DT_RELENT and DT_RELAENT do not change, but make sure they are what
792 // we expect. Only one will be present. 793 // we expect. Only one will be present.
793 if (tag == DT_RELENT || tag == DT_RELAENT) { 794 if (tag == DT_RELENT || tag == DT_RELAENT) {
794 CHECK(dynamic->d_un.d_val == sizeof(Rel)); 795 CHECK(dynamic->d_un.d_val == sizeof(Rel));
795 } 796 }
796 } 797 }
797 798
798 void* section_data = &dynamics[0]; 799 void* section_data = &dynamics[0];
799 size_t bytes = dynamics.size() * sizeof(dynamics[0]); 800 size_t bytes = dynamics.size() * sizeof(dynamics[0]);
800 RewriteSectionData(data, section_data, bytes); 801 RewriteSectionData(dynamic_section, section_data, bytes);
801 } 802 }
802 803
803 // Resize a section. If the new size is larger than the current size, open 804 // Resize a section. If the new size is larger than the current size, open
804 // up a hole by increasing file offsets that come after the hole. If smaller 805 // up a hole by increasing file offsets that come after the hole. If smaller
805 // than the current size, remove the hole by decreasing those offsets. 806 // than the current size, remove the hole by decreasing those offsets.
806 template <typename Rel> 807 template <typename Rel>
807 void ResizeSection(Elf* elf, Elf_Scn* section, size_t new_size) { 808 void ResizeSection(Elf* elf, Elf_Scn* section, size_t new_size) {
808 ELF::Shdr* section_header = ELF::getshdr(section); 809 ELF::Shdr* section_header = ELF::getshdr(section);
809 if (section_header->sh_size == new_size) 810 if (section_header->sh_size == new_size)
810 return; 811 return;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 Elf_Data* data = GetSectionData(relocations_section_); 946 Elf_Data* data = GetSectionData(relocations_section_);
946 947
947 if (relocations_type_ == REL) { 948 if (relocations_type_ == REL) {
948 // Convert data to a vector of relocations. 949 // Convert data to a vector of relocations.
949 const ELF::Rel* relocations_base = reinterpret_cast<ELF::Rel*>(data->d_buf); 950 const ELF::Rel* relocations_base = reinterpret_cast<ELF::Rel*>(data->d_buf);
950 std::vector<ELF::Rel> relocations( 951 std::vector<ELF::Rel> relocations(
951 relocations_base, 952 relocations_base,
952 relocations_base + data->d_size / sizeof(relocations[0])); 953 relocations_base + data->d_size / sizeof(relocations[0]));
953 954
954 LOG(INFO) << "Relocations : REL"; 955 LOG(INFO) << "Relocations : REL";
955 return PackTypedRelocations<ELF::Rel>(relocations, data); 956 return PackTypedRelocations<ELF::Rel>(relocations);
956 } 957 }
957 958
958 if (relocations_type_ == RELA) { 959 if (relocations_type_ == RELA) {
959 // Convert data to a vector of relocations with addends. 960 // Convert data to a vector of relocations with addends.
960 const ELF::Rela* relocations_base = 961 const ELF::Rela* relocations_base =
961 reinterpret_cast<ELF::Rela*>(data->d_buf); 962 reinterpret_cast<ELF::Rela*>(data->d_buf);
962 std::vector<ELF::Rela> relocations( 963 std::vector<ELF::Rela> relocations(
963 relocations_base, 964 relocations_base,
964 relocations_base + data->d_size / sizeof(relocations[0])); 965 relocations_base + data->d_size / sizeof(relocations[0]));
965 966
966 LOG(INFO) << "Relocations : RELA"; 967 LOG(INFO) << "Relocations : RELA";
967 return PackTypedRelocations<ELF::Rela>(relocations, data); 968 return PackTypedRelocations<ELF::Rela>(relocations);
968 } 969 }
969 970
970 NOTREACHED(); 971 NOTREACHED();
971 return false; 972 return false;
972 } 973 }
973 974
974 // Helper for PackRelocations(). Rel type is one of ELF::Rel or ELF::Rela. 975 // Helper for PackRelocations(). Rel type is one of ELF::Rel or ELF::Rela.
975 template <typename Rel> 976 template <typename Rel>
976 bool ElfFile::PackTypedRelocations(const std::vector<Rel>& relocations, 977 bool ElfFile::PackTypedRelocations(const std::vector<Rel>& relocations) {
977 Elf_Data* data) {
978 // Filter relocations into those that are relative and others. 978 // Filter relocations into those that are relative and others.
979 std::vector<Rel> relative_relocations; 979 std::vector<Rel> relative_relocations;
980 std::vector<Rel> other_relocations; 980 std::vector<Rel> other_relocations;
981 981
982 for (size_t i = 0; i < relocations.size(); ++i) { 982 for (size_t i = 0; i < relocations.size(); ++i) {
983 const Rel& relocation = relocations[i]; 983 const Rel& relocation = relocations[i];
984 if (ELF_R_TYPE(relocation.r_info) == ELF::kRelativeRelocationCode) { 984 if (ELF_R_TYPE(relocation.r_info) == ELF::kRelativeRelocationCode) {
985 CHECK(ELF_R_SYM(relocation.r_info) == 0); 985 CHECK(ELF_R_SYM(relocation.r_info) == 0);
986 relative_relocations.push_back(relocation); 986 relative_relocations.push_back(relocation);
987 } else { 987 } else {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 if (packed_bytes >= initial_bytes) { 1078 if (packed_bytes >= initial_bytes) {
1079 LOG(INFO) << "Packing relative relocations saves no space"; 1079 LOG(INFO) << "Packing relative relocations saves no space";
1080 return false; 1080 return false;
1081 } 1081 }
1082 1082
1083 // Rewrite the current dynamic relocations section to be only the ARM 1083 // Rewrite the current dynamic relocations section to be only the ARM
1084 // non-relative relocations, then shrink it to size. 1084 // non-relative relocations, then shrink it to size.
1085 const void* section_data = &other_relocations[0]; 1085 const void* section_data = &other_relocations[0];
1086 const size_t bytes = other_relocations.size() * sizeof(other_relocations[0]); 1086 const size_t bytes = other_relocations.size() * sizeof(other_relocations[0]);
1087 ResizeSection<Rel>(elf_, relocations_section_, bytes); 1087 ResizeSection<Rel>(elf_, relocations_section_, bytes);
1088 RewriteSectionData(data, section_data, bytes); 1088 RewriteSectionData(relocations_section_, section_data, bytes);
1089 1089
1090 // Rewrite the current packed android relocations section to hold the packed 1090 // Rewrite the current packed android relocations section to hold the packed
1091 // relative relocations. 1091 // relative relocations.
1092 data = GetSectionData(android_relocations_section_);
1093 ResizeSection<Rel>(elf_, android_relocations_section_, packed_bytes); 1092 ResizeSection<Rel>(elf_, android_relocations_section_, packed_bytes);
1094 RewriteSectionData(data, packed_data, packed_bytes); 1093 RewriteSectionData(android_relocations_section_, packed_data, packed_bytes);
1095 1094
1096 // Rewrite .dynamic to include two new tags describing the packed android 1095 // Rewrite .dynamic to include two new tags describing the packed android
1097 // relocations. 1096 // relocations.
1098 data = GetSectionData(dynamic_section_); 1097 Elf_Data* data = GetSectionData(dynamic_section_);
1099 const ELF::Dyn* dynamic_base = reinterpret_cast<ELF::Dyn*>(data->d_buf); 1098 const ELF::Dyn* dynamic_base = reinterpret_cast<ELF::Dyn*>(data->d_buf);
1100 std::vector<ELF::Dyn> dynamics( 1099 std::vector<ELF::Dyn> dynamics(
1101 dynamic_base, 1100 dynamic_base,
1102 dynamic_base + data->d_size / sizeof(dynamics[0])); 1101 dynamic_base + data->d_size / sizeof(dynamics[0]));
1103 // Use two of the spare slots to describe the packed section. 1102 // Use two of the spare slots to describe the packed section.
1104 ELF::Shdr* section_header = ELF::getshdr(android_relocations_section_); 1103 ELF::Shdr* section_header = ELF::getshdr(android_relocations_section_);
1105 { 1104 {
1106 ELF::Dyn dyn; 1105 ELF::Dyn dyn;
1107 dyn.d_tag = DT_ANDROID_REL_OFFSET; 1106 dyn.d_tag = DT_ANDROID_REL_OFFSET;
1108 dyn.d_un.d_ptr = section_header->sh_offset; 1107 dyn.d_un.d_ptr = section_header->sh_offset;
1109 AddDynamicEntry(dyn, &dynamics); 1108 AddDynamicEntry(dyn, &dynamics);
1110 } 1109 }
1111 { 1110 {
1112 ELF::Dyn dyn; 1111 ELF::Dyn dyn;
1113 dyn.d_tag = DT_ANDROID_REL_SIZE; 1112 dyn.d_tag = DT_ANDROID_REL_SIZE;
1114 dyn.d_un.d_val = section_header->sh_size; 1113 dyn.d_un.d_val = section_header->sh_size;
1115 AddDynamicEntry(dyn, &dynamics); 1114 AddDynamicEntry(dyn, &dynamics);
1116 } 1115 }
1117 const void* dynamics_data = &dynamics[0]; 1116 const void* dynamics_data = &dynamics[0];
1118 const size_t dynamics_bytes = dynamics.size() * sizeof(dynamics[0]); 1117 const size_t dynamics_bytes = dynamics.size() * sizeof(dynamics[0]);
1119 RewriteSectionData(data, dynamics_data, dynamics_bytes); 1118 RewriteSectionData(dynamic_section_, dynamics_data, dynamics_bytes);
1120 1119
1121 Flush(); 1120 Flush();
1122 return true; 1121 return true;
1123 } 1122 }
1124 1123
1125 // Find packed relative relocations in the packed android relocations 1124 // Find packed relative relocations in the packed android relocations
1126 // section, unpack them, and rewrite the dynamic relocations section to 1125 // section, unpack them, and rewrite the dynamic relocations section to
1127 // contain unpacked data. 1126 // contain unpacked data.
1128 bool ElfFile::UnpackRelocations() { 1127 bool ElfFile::UnpackRelocations() {
1129 // Load the ELF file into libelf. 1128 // Load the ELF file into libelf.
(...skipping 12 matching lines...) Expand all
1142 packed_base + data->d_size / sizeof(packed[0])); 1141 packed_base + data->d_size / sizeof(packed[0]));
1143 1142
1144 if (packed.size() > 3 && 1143 if (packed.size() > 3 &&
1145 packed[0] == 'A' && 1144 packed[0] == 'A' &&
1146 packed[1] == 'P' && 1145 packed[1] == 'P' &&
1147 packed[2] == 'R' && 1146 packed[2] == 'R' &&
1148 packed[3] == '1') { 1147 packed[3] == '1') {
1149 // Signature is APR1, unpack relocations. 1148 // Signature is APR1, unpack relocations.
1150 CHECK(relocations_type_ == REL); 1149 CHECK(relocations_type_ == REL);
1151 LOG(INFO) << "Relocations : REL"; 1150 LOG(INFO) << "Relocations : REL";
1152 return UnpackTypedRelocations<ELF::Rel>(packed, data); 1151 return UnpackTypedRelocations<ELF::Rel>(packed);
1153 } 1152 }
1154 1153
1155 if (packed.size() > 3 && 1154 if (packed.size() > 3 &&
1156 packed[0] == 'A' && 1155 packed[0] == 'A' &&
1157 packed[1] == 'P' && 1156 packed[1] == 'P' &&
1158 packed[2] == 'A' && 1157 packed[2] == 'A' &&
1159 packed[3] == '1') { 1158 packed[3] == '1') {
1160 // Signature is APA1, unpack relocations with addends. 1159 // Signature is APA1, unpack relocations with addends.
1161 CHECK(relocations_type_ == RELA); 1160 CHECK(relocations_type_ == RELA);
1162 LOG(INFO) << "Relocations : RELA"; 1161 LOG(INFO) << "Relocations : RELA";
1163 return UnpackTypedRelocations<ELF::Rela>(packed, data); 1162 return UnpackTypedRelocations<ELF::Rela>(packed);
1164 } 1163 }
1165 1164
1166 LOG(ERROR) << "Packed relative relocations not found (not packed?)"; 1165 LOG(ERROR) << "Packed relative relocations not found (not packed?)";
1167 return false; 1166 return false;
1168 } 1167 }
1169 1168
1170 // Helper for UnpackRelocations(). Rel type is one of ELF::Rel or ELF::Rela. 1169 // Helper for UnpackRelocations(). Rel type is one of ELF::Rel or ELF::Rela.
1171 template <typename Rel> 1170 template <typename Rel>
1172 bool ElfFile::UnpackTypedRelocations(const std::vector<uint8_t>& packed, 1171 bool ElfFile::UnpackTypedRelocations(const std::vector<uint8_t>& packed) {
1173 Elf_Data* data) {
1174 // Unpack the data to re-materialize the relative relocations. 1172 // Unpack the data to re-materialize the relative relocations.
1175 const size_t packed_bytes = packed.size() * sizeof(packed[0]); 1173 const size_t packed_bytes = packed.size() * sizeof(packed[0]);
1176 LOG(INFO) << "Packed relative: " << packed_bytes << " bytes"; 1174 LOG(INFO) << "Packed relative: " << packed_bytes << " bytes";
1177 std::vector<Rel> relative_relocations; 1175 std::vector<Rel> relative_relocations;
1178 RelocationPacker packer; 1176 RelocationPacker packer;
1179 packer.UnpackRelativeRelocations(packed, &relative_relocations); 1177 packer.UnpackRelativeRelocations(packed, &relative_relocations);
1180 const size_t unpacked_bytes = 1178 const size_t unpacked_bytes =
1181 relative_relocations.size() * sizeof(relative_relocations[0]); 1179 relative_relocations.size() * sizeof(relative_relocations[0]);
1182 LOG(INFO) << "Unpacked relative: " << unpacked_bytes << " bytes"; 1180 LOG(INFO) << "Unpacked relative: " << unpacked_bytes << " bytes";
1183 1181
1184 // Retrieve the current dynamic relocations section data. 1182 // Retrieve the current dynamic relocations section data.
1185 data = GetSectionData(relocations_section_); 1183 Elf_Data* data = GetSectionData(relocations_section_);
1186 1184
1187 // Interpret data as relocations. 1185 // Interpret data as relocations.
1188 const Rel* relocations_base = reinterpret_cast<Rel*>(data->d_buf); 1186 const Rel* relocations_base = reinterpret_cast<Rel*>(data->d_buf);
1189 std::vector<Rel> relocations( 1187 std::vector<Rel> relocations(
1190 relocations_base, 1188 relocations_base,
1191 relocations_base + data->d_size / sizeof(relocations[0])); 1189 relocations_base + data->d_size / sizeof(relocations[0]));
1192 1190
1193 std::vector<Rel> other_relocations; 1191 std::vector<Rel> other_relocations;
1194 size_t padding = 0; 1192 size_t padding = 0;
1195 1193
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 // relocations followed by other relocations. This is the usual order in 1225 // relocations followed by other relocations. This is the usual order in
1228 // which we find them after linking, so this action will normally put the 1226 // which we find them after linking, so this action will normally put the
1229 // entire dynamic relocations section back to its pre-split-and-packed state. 1227 // entire dynamic relocations section back to its pre-split-and-packed state.
1230 relocations.assign(relative_relocations.begin(), relative_relocations.end()); 1228 relocations.assign(relative_relocations.begin(), relative_relocations.end());
1231 relocations.insert(relocations.end(), 1229 relocations.insert(relocations.end(),
1232 other_relocations.begin(), other_relocations.end()); 1230 other_relocations.begin(), other_relocations.end());
1233 const void* section_data = &relocations[0]; 1231 const void* section_data = &relocations[0];
1234 const size_t bytes = relocations.size() * sizeof(relocations[0]); 1232 const size_t bytes = relocations.size() * sizeof(relocations[0]);
1235 LOG(INFO) << "Total : " << relocations.size() << " entries"; 1233 LOG(INFO) << "Total : " << relocations.size() << " entries";
1236 ResizeSection<Rel>(elf_, relocations_section_, bytes); 1234 ResizeSection<Rel>(elf_, relocations_section_, bytes);
1237 RewriteSectionData(data, section_data, bytes); 1235 RewriteSectionData(relocations_section_, section_data, bytes);
1238 1236
1239 // Nearly empty the current packed android relocations section. Leaves a 1237 // Nearly empty the current packed android relocations section. Leaves a
1240 // four-byte stub so that some data remains allocated to the section. 1238 // four-byte stub so that some data remains allocated to the section.
1241 // This is a convenience which allows us to re-pack this file again without 1239 // This is a convenience which allows us to re-pack this file again without
1242 // having to remove the section and then add a new small one with objcopy. 1240 // having to remove the section and then add a new small one with objcopy.
1243 // The way we resize sections relies on there being some data in a section. 1241 // The way we resize sections relies on there being some data in a section.
1244 data = GetSectionData(android_relocations_section_);
1245 ResizeSection<Rel>( 1242 ResizeSection<Rel>(
1246 elf_, android_relocations_section_, sizeof(kStubIdentifier)); 1243 elf_, android_relocations_section_, sizeof(kStubIdentifier));
1247 RewriteSectionData(data, &kStubIdentifier, sizeof(kStubIdentifier)); 1244 RewriteSectionData(
1245 android_relocations_section_, &kStubIdentifier, sizeof(kStubIdentifier));
1248 1246
1249 // Rewrite .dynamic to remove two tags describing packed android relocations. 1247 // Rewrite .dynamic to remove two tags describing packed android relocations.
1250 data = GetSectionData(dynamic_section_); 1248 data = GetSectionData(dynamic_section_);
1251 const ELF::Dyn* dynamic_base = reinterpret_cast<ELF::Dyn*>(data->d_buf); 1249 const ELF::Dyn* dynamic_base = reinterpret_cast<ELF::Dyn*>(data->d_buf);
1252 std::vector<ELF::Dyn> dynamics( 1250 std::vector<ELF::Dyn> dynamics(
1253 dynamic_base, 1251 dynamic_base,
1254 dynamic_base + data->d_size / sizeof(dynamics[0])); 1252 dynamic_base + data->d_size / sizeof(dynamics[0]));
1255 RemoveDynamicEntry(DT_ANDROID_REL_OFFSET, &dynamics); 1253 RemoveDynamicEntry(DT_ANDROID_REL_OFFSET, &dynamics);
1256 RemoveDynamicEntry(DT_ANDROID_REL_SIZE, &dynamics); 1254 RemoveDynamicEntry(DT_ANDROID_REL_SIZE, &dynamics);
1257 const void* dynamics_data = &dynamics[0]; 1255 const void* dynamics_data = &dynamics[0];
1258 const size_t dynamics_bytes = dynamics.size() * sizeof(dynamics[0]); 1256 const size_t dynamics_bytes = dynamics.size() * sizeof(dynamics[0]);
1259 RewriteSectionData(data, dynamics_data, dynamics_bytes); 1257 RewriteSectionData(dynamic_section_, dynamics_data, dynamics_bytes);
1260 1258
1261 Flush(); 1259 Flush();
1262 return true; 1260 return true;
1263 } 1261 }
1264 1262
1265 // Flush rewritten shared object file data. 1263 // Flush rewritten shared object file data.
1266 void ElfFile::Flush() { 1264 void ElfFile::Flush() {
1267 // Flag all ELF data held in memory as needing to be written back to the 1265 // Flag all ELF data held in memory as needing to be written back to the
1268 // file, and tell libelf that we have controlled the file layout. 1266 // file, and tell libelf that we have controlled the file layout.
1269 elf_flagelf(elf_, ELF_C_SET, ELF_F_DIRTY); 1267 elf_flagelf(elf_, ELF_C_SET, ELF_F_DIRTY);
1270 elf_flagelf(elf_, ELF_C_SET, ELF_F_LAYOUT); 1268 elf_flagelf(elf_, ELF_C_SET, ELF_F_LAYOUT);
1271 1269
1272 // Write ELF data back to disk. 1270 // Write ELF data back to disk.
1273 const off_t file_bytes = elf_update(elf_, ELF_C_WRITE); 1271 const off_t file_bytes = elf_update(elf_, ELF_C_WRITE);
1274 CHECK(file_bytes > 0); 1272 CHECK(file_bytes > 0);
1275 VLOG(1) << "elf_update returned: " << file_bytes; 1273 VLOG(1) << "elf_update returned: " << file_bytes;
1276 1274
1277 // Clean up libelf, and truncate the output file to the number of bytes 1275 // Clean up libelf, and truncate the output file to the number of bytes
1278 // written by elf_update(). 1276 // written by elf_update().
1279 elf_end(elf_); 1277 elf_end(elf_);
1280 elf_ = NULL; 1278 elf_ = NULL;
1281 const int truncate = ftruncate(fd_, file_bytes); 1279 const int truncate = ftruncate(fd_, file_bytes);
1282 CHECK(truncate == 0); 1280 CHECK(truncate == 0);
1283 } 1281 }
1284 1282
1285 } // namespace relocation_packer 1283 } // namespace relocation_packer
OLDNEW
« no previous file with comments | « tools/relocation_packer/src/elf_file.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698