@@ -119,14 +119,15 @@ bool ElfReader::Load() {
119
119
return ReadElfHeader () &&
120
120
VerifyElfHeader () &&
121
121
ReadProgramHeader () &&
122
+ // TODO READ dynamic from SECTION header (>= __ANDROID_API_O__)
122
123
ReserveAddressSpace () &&
123
124
LoadSegments () &&
124
125
FindPhdr () &&
125
126
PatchPhdr ();
126
127
}
127
128
128
129
bool ElfReader::ReadElfHeader () {
129
- ssize_t rc = read (fd_, &header_, sizeof (header_));
130
+ ssize_t rc = TEMP_FAILURE_RETRY ( read (fd_, &header_, sizeof (header_) ));
130
131
if (rc < 0 ) {
131
132
FLOGE (" can't read file \" %s\" : %s" , name_, strerror (errno));
132
133
return false ;
@@ -201,30 +202,35 @@ bool ElfReader::ReadProgramHeader() {
201
202
if (dump_so_file_) {
202
203
auto phdr = phdr_table_;
203
204
for (auto i = 0 ; i < phdr_num_; i++) {
204
- phdr->p_filesz = phdr->p_memsz ; // expend filesize to memsiz
205
205
phdr->p_paddr = phdr->p_vaddr ;
206
- phdr->p_offset = phdr->p_vaddr ; // elf has been loaded.
206
+ phdr->p_filesz = phdr->p_memsz ; // expend filesize to memsiz
207
+ phdr->p_offset = phdr->p_vaddr ; // since elf has been loaded. just expand file data to dump memory data
208
+ // phdr->p_flags = 0 // TODO fix flags by PT_TYPE
207
209
phdr++;
208
210
}
209
- // fix phdr, just load all data
211
+ // some shell will release data between loadable phdr(s) , just load all memory data
210
212
std::vector<Elf_Phdr*> loaded_phdrs;
211
213
for (auto i = 0 ; i < phdr_num_; i++) {
212
214
auto phdr = &phdr_table_[i];
213
215
if (phdr->p_type != PT_LOAD) continue ;
214
216
loaded_phdrs.push_back (phdr);
215
217
}
218
+ std::sort (loaded_phdrs.begin (), loaded_phdrs.end (),
219
+ [](Elf_Phdr * first, Elf_Phdr * second) {
220
+ return first->p_vaddr < second->p_vaddr ;
221
+ });
216
222
if (!loaded_phdrs.empty ()) {
217
223
for (unsigned long i = 0 , total = loaded_phdrs.size (); i < total; i++) {
218
224
auto phdr = loaded_phdrs[i];
219
- if (i != total - 1 ) {
220
- // to next loaded segament
221
- auto nphdr = loaded_phdrs[i+1 ];
222
- phdr->p_memsz = nphdr->p_vaddr - phdr->p_vaddr ;
223
- } else {
224
- // to the file end
225
- phdr->p_memsz = file_size - phdr->p_vaddr ;
226
- }
227
- phdr->p_filesz = phdr->p_memsz ;
225
+ if (i != total - 1 ) {
226
+ // to next loaded segament
227
+ auto nphdr = loaded_phdrs[i+1 ];
228
+ phdr->p_memsz = nphdr->p_vaddr - phdr->p_vaddr ;
229
+ } else {
230
+ // to the file end
231
+ phdr->p_memsz = file_size - phdr->p_vaddr ;
232
+ }
233
+ phdr->p_filesz = phdr->p_memsz ;
228
234
}
229
235
}
230
236
}
@@ -246,7 +252,11 @@ size_t phdr_table_get_load_size(const Elf_Phdr* phdr_table,
246
252
Elf_Addr* out_min_vaddr,
247
253
Elf_Addr* out_max_vaddr)
248
254
{
249
- Elf_Addr min_vaddr = 0xFFFFFFFFU ;
255
+ #ifdef __SO64__
256
+ Elf_Addr min_vaddr = UINT64_MAX;
257
+ #else
258
+ Elf_Addr min_vaddr = UINT_MAX;
259
+ #endif
250
260
Elf_Addr max_vaddr = 0x00000000U ;
251
261
252
262
bool found_pt_load = false ;
@@ -296,8 +306,11 @@ bool ElfReader::ReserveAddressSpace() {
296
306
uint8_t * addr = reinterpret_cast <uint8_t *>(min_vaddr);
297
307
// alloc map data, and load in addr
298
308
uint8_t * start = new uint8_t [load_size_];
309
+ memset (start, 0 , load_size_);
299
310
300
311
load_start_ = start;
312
+ // the first loaded phdr data should be loaded in the start of load_start
313
+ // (load_bias_ + phdr.vaddr), so load_bias_ = load_start - phdr.vaddr(min_addr)
301
314
load_bias_ = reinterpret_cast <uint8_t *>(reinterpret_cast <uintptr_t >(start)
302
315
- reinterpret_cast <uintptr_t >(addr));
303
316
return true ;
@@ -320,23 +333,23 @@ bool ElfReader::LoadSegments() {
320
333
Elf_Addr seg_start = phdr->p_vaddr ;
321
334
Elf_Addr seg_end = seg_start + phdr->p_memsz ;
322
335
323
- Elf_Addr seg_page_start = PAGE_START (seg_start);
324
- Elf_Addr seg_page_end = PAGE_END (seg_end);
336
+ // Elf_Addr seg_page_start = PAGE_START(seg_start);
337
+ // Elf_Addr seg_page_end = PAGE_END(seg_end);
325
338
326
339
Elf_Addr seg_file_end = seg_start + phdr->p_filesz ;
327
340
328
341
// File offsets.
329
342
Elf_Addr file_start = phdr->p_offset ;
330
343
Elf_Addr file_end = file_start + phdr->p_filesz ;
331
344
332
- Elf_Addr file_page_start = PAGE_START (file_start);
333
- Elf_Addr file_length = file_end - file_page_start ;
345
+ // Elf_Addr file_page_start = PAGE_START(file_start);
346
+ Elf_Addr file_length = file_end - file_start ;
334
347
335
348
336
349
if (file_length != 0 ) {
337
350
// memory data loading
338
- void * load_point = seg_page_start + reinterpret_cast <uint8_t *>(load_bias_);
339
- if (!LoadFileData (load_point, file_length, file_page_start )) {
351
+ void * load_point = seg_start + reinterpret_cast <uint8_t *>(load_bias_);
352
+ if (!LoadFileData (load_point, file_length, file_start )) {
340
353
FLOGE (" couldn't map \" %s\" segment %zu: %s" , name_, i, strerror (errno));
341
354
return false ;
342
355
}
@@ -345,20 +358,21 @@ bool ElfReader::LoadSegments() {
345
358
346
359
// if the segment is writable, and does not end on a page boundary,
347
360
// zero-fill it until the page limit.
348
- if ((phdr->p_flags & PF_W) != 0 && PAGE_OFFSET (seg_file_end) > 0 ) {
349
- memset (seg_file_end + reinterpret_cast <uint8_t *>(load_bias_), 0 , PAGE_SIZE - PAGE_OFFSET (seg_file_end));
350
- }
361
+ // if ((phdr->p_flags & PF_W) != 0 && PAGE_OFFSET(seg_file_end) > 0) {
362
+ // memset(seg_file_end + reinterpret_cast<uint8_t *>(load_bias_), 0, PAGE_SIZE - PAGE_OFFSET(seg_file_end));
363
+ // }
351
364
352
- seg_file_end = PAGE_END (seg_file_end);
365
+ // seg_file_end = PAGE_END(seg_file_end);
353
366
354
367
// seg_file_end is now the first page address after the file
355
368
// content. If seg_end is larger, we need to zero anything
356
369
// between them. This is done by using a private anonymous
357
370
// map for all extra pages.
358
- if (seg_page_end > seg_file_end) {
359
- void * load_point = (uint8_t *)load_bias_ + seg_file_end;
360
- memset (load_point, 0 , seg_page_end - seg_file_end);
361
- }
371
+ // since data has been clear, just skip this step
372
+ // if (seg_page_end > seg_file_end) {
373
+ // void* load_point = (uint8_t*)load_bias_ + seg_file_end;
374
+ // memset(load_point, 0, seg_page_end - seg_file_end);
375
+ // }
362
376
}
363
377
return true ;
364
378
}
@@ -661,7 +675,7 @@ bool ElfReader::CheckPhdr(uint8_t * loaded) {
661
675
662
676
bool ElfReader::LoadFileData (void *addr, size_t len, int offset) {
663
677
lseek (fd_, offset, SEEK_SET);
664
- auto rc = read (fd_, addr, len);
678
+ auto rc = TEMP_FAILURE_RETRY ( read (fd_, addr, len) );
665
679
666
680
if (rc < 0 ) {
667
681
FLOGE (" can't read file \" %s\" : %s" , name_, strerror (errno));
0 commit comments