6 #include "AsmUnparser_compat.h"
9 #include <boost/math/common_factor.hpp>
19 ROSE_ASSERT(
this != NULL);
21 ROSE_ASSERT(
p_fd == -1);
40 ROSE_ASSERT(
p_fd < 0);
43 p_fd = open(fileName.c_str(), O_RDONLY);
45 std::string mesg =
"Could not open binary file";
48 size_t nbytes =
p_sb.st_size;
51 unsigned char *mapped =
new unsigned char[nbytes];
53 throw FormatError(
"Could not allocate memory for binary file");
54 ssize_t nread = read(
p_fd, mapped, nbytes);
55 if (nread<0 || (
size_t)nread!=nbytes)
58 throw FormatError(
"Could not read entire binary file");
64 unsigned char *new_mapped = dc->
decode(mapped, &nbytes);
65 if (new_mapped!=mapped) {
104 for (SgAsmGenericSectionPtrList::iterator i=sections.begin(); i!=sections.end(); ++i) {
105 retval =
std::max(retval, (*i)->get_end_offset());
153 memcpy(dst_buf, &(
p_data[offset]), retval);
156 memset((
char*)dst_buf+retval, 0, size-retval);
167 ROSE_ASSERT(map!=NULL);
172 while (ncopied < size) {
179 std::pair<Extent, MemoryMap::Segment> me = map->
at(va);
180 if (me.second.get_buffer()->get_data_ptr()==&(
get_data()[0])) {
182 size_t file_offset = me.second.get_buffer_offset(me.first, va);
192 throw MemoryMap::NotMapped(
"SgAsmGenericFile::read_content() no mapping", map, start_va+ncopied);
193 memset((
char*)dst_buf+ncopied, 0, size-ncopied);
206 static char *buf=NULL;
207 static size_t nalloc=0;
213 if (nused >= nalloc) {
214 nalloc =
std::max((
size_t)32, 2*nalloc);
215 buf = (
char*)realloc(buf, nalloc);
216 ROSE_ASSERT(buf!=NULL);
222 return std::string(buf, nused);
235 static char *buf=NULL;
236 static size_t nalloc=0;
242 if (nused >= nalloc) {
243 nalloc =
std::max((
size_t)32, 2*nalloc);
244 buf = (
char*)realloc(buf, nalloc);
245 ROSE_ASSERT(buf!=NULL);
251 return std::string(buf, nused);
345 if ((*i)->get_sections()!=NULL) {
347 retval.insert(retval.end(), recurse.begin(), recurse.end());
359 for (
size_t i=0; i<all.size(); i++) {
360 if (all[i]->is_mapped())
361 retval.push_back(all[i]);
374 if ((*i)->get_id()==id)
375 retval.push_back(*i);
380 if ((*i)->get_id()==id)
381 retval.push_back(*i);
383 retval.insert(retval.end(), recurse.begin(), recurse.end());
394 if (nfound) *nfound = possible.size();
395 return possible.size()==1 ? possible[0] : NULL;
406 size_t pos = name.find(sep);
413 std::string secname = (*i)->get_name()->get_string();
415 size_t pos = secname.find(sep);
416 if (pos!=secname.npos)
419 if (0==secname.compare(name))
420 retval.push_back(*i);
425 std::string secname = (*i)->get_name()->get_string();
427 size_t pos = secname.find(sep);
428 if (pos!=secname.npos)
431 if (0==secname.compare(name))
432 retval.push_back(*i);
435 retval.insert(retval.end(), recurse.begin(), recurse.end());
447 if (nfound) *nfound = possible.size();
448 return possible.size()==1 ? possible[0] : NULL;
459 if (offset >= (*i)->get_offset() &&
460 offset < (*i)->get_offset()+(*i)->get_size() &&
461 offset-(*i)->get_offset() + size <= (*i)->get_size())
462 retval.push_back(*i);
467 if (offset >= (*i)->get_offset() &&
468 offset < (*i)->get_offset()+(*i)->get_size() &&
469 offset-(*i)->get_offset() + size <= (*i)->get_size())
470 retval.push_back(*i);
472 retval.insert(retval.end(), recurse.begin(), recurse.end());
483 if (nfound) *nfound = possible.size();
484 return possible.size()==1 ? possible[0] : NULL;
496 if ((*i)->is_mapped() &&
497 rva >= (*i)->get_mapped_preferred_rva() && rva < (*i)->get_mapped_preferred_rva() + (*i)->get_mapped_size())
498 retval.push_back(*i);
503 if ((*i)->is_mapped() &&
504 rva >= (*i)->get_mapped_preferred_rva() && rva < (*i)->get_mapped_preferred_rva() + (*i)->get_mapped_size())
505 retval.push_back(*i);
507 retval.insert(retval.end(), recurse.begin(), recurse.end());
518 if (nfound) *nfound = possible.size();
519 return possible.size()==1 ? possible[0] : NULL;
532 if ((*i)->is_mapped() &&
533 rva >= (*i)->get_mapped_preferred_rva() && rva < (*i)->get_mapped_preferred_rva() + (*i)->get_mapped_size())
534 retval.push_back(*i);
541 if ((*i)->is_mapped() &&
542 rva >= (*i)->get_mapped_preferred_rva() && rva < (*i)->get_mapped_preferred_rva() + (*i)->get_mapped_size())
543 retval.push_back(*i);
547 retval.insert(retval.end(), recurse.begin(), recurse.end());
558 if (nfound) *nfound = possible.size();
559 return possible.size()==1 ? possible[0] : NULL;
570 *nfound = candidates.size();
587 for (SgAsmGenericSectionPtrList::const_iterator si=sections.begin(); si!=sections.end(); ++si) {
620 if (0 == possible.size())
626 if (1 == possible.size())
631 if (possible[0]->get_id() < 0)
639 printf (
"Select from %zu alternatives \n",possible.size());
640 for (
size_t i = 0; i < possible.size(); i++)
642 printf (
" va = %p possible[%zu] id = %d name = %s \n",(
void*)va,i,possible[i]->get_id(),possible[i]->
get_name().c_str());
649 for (
size_t i = 1; i < possible.size(); i++)
651 if (fo0 != possible[i]->get_va_offset(va))
654 if (best->
get_id() < 0 && possible[i]->get_id() > 0)
664 if (best->
get_name()->
get_string().size()==0 && possible[i]->get_name()->get_string().size()>0)
675 ROSE_ASSERT(best != NULL);
693 for (SgAsmGenericSectionPtrList::const_iterator i=sections.begin(); i!=sections.end(); ++i) {
694 if ((*i)->get_offset() >= offset && (*i)->get_offset() < found)
695 found = (*i)->get_offset();
739 ROSE_ASSERT(s!=NULL);
743 const bool debug =
false;
744 static size_t ncalls=0;
748 const char *space_s=
"unknown";
754 sprintf(p,
"SgAsmGenericFile::shift_extend[%zu]: ", ncalls++);
755 fprintf(stderr,
"%s -- START --\n", p);
757 fprintf(stderr,
"%s %s Sa=0x%08"PRIx64
" (%"PRIu64
"), Sn=0x%08"PRIx64
" (%"PRIu64
")\n", p, space_s, sa, sa, sn, sn);
758 fprintf(stderr,
"%s elasticity = %s\n", p, (
ELASTIC_NONE==elasticity ?
"none" :
765 if (0==sa && 0==sn) {
767 fprintf(stderr,
"%s No change necessary.\n", p);
768 fprintf(stderr,
"%s -- END --\n", p);
782 switch (elasticity) {
792 fprintf(stderr,
"%s Following sections are in 'all' set:\n", p);
793 for (
size_t i=0; i<all.size(); i++) {
796 ep = all[i]->get_file_extent();
798 ROSE_ASSERT(all[i]->is_mapped());
799 ep = all[i]->get_mapped_preferred_extent();
801 fprintf(stderr,
"%s 0x%08"PRIx64
" 0x%08"PRIx64
" 0x%08"PRIx64
" [%d] \"%s\"\n",
803 all[i]->get_name()->get_string(
true).c_str());
807 for (
size_t pass=0; pass<2; pass++) {
809 fprintf(stderr,
"%s -- %s --\n",
810 p, 0==pass?
"FIRST PASS":
"SECOND PASS (after making a larger hole)");
816 }
else if (!memspace || !s->
is_mapped()) {
823 for (
size_t i=0; i<all.size(); i++) {
825 amap.
insert(all[i]->get_file_extent());
827 ROSE_ASSERT(all[i]->is_mapped());
828 amap.
insert(all[i]->get_mapped_preferred_extent());
832 fprintf(stderr,
"%s Address map:\n", p);
833 amap.
dump_extents(stderr, (std::string(p)+
" ").c_str(),
"amap");
834 fprintf(stderr,
"%s Extent of S:\n", p);
835 fprintf(stderr,
"%s start=0x%08"PRIx64
" size=0x%08"PRIx64
" end=0x%08"PRIx64
"\n",
844 amapi->first.relaxed_first()+amapi->first.size() > sp.
relaxed_first())
845 nhs_map.
insert(amapi->first, amapi->second);
848 fprintf(stderr,
"%s Neighborhood of S:\n", p);
849 nhs_map.
dump_extents(stderr, (std::string(p)+
" ").c_str(),
"nhs_map");
852 if (nhs_map.
size()>0) {
854 nhs = nhs_map.
begin()->first;
861 neighbors.push_back(s);
864 fprintf(stderr,
"%s Ignoring left (L) sections:\n", p);
865 for (
size_t i=0; i<all.size(); i++) {
879 fprintf(stderr,
"%s L 0x%08"PRIx64
" 0x%08"PRIx64
" 0x%08"PRIx64
" [%d] \"%s\"\n",
887 neighbors.push_back(a);
892 villagers.push_back(a);
896 neighbors.push_back(a);
901 neighbors.push_back(a);
906 fprintf(stderr,
"%s Neighbors:\n", p);
907 for (
size_t i=0; i<neighbors.size(); i++) {
912 fprintf(stderr,
"%s %c %c0x%08"PRIx64
" 0x%08"PRIx64
" 0x%08"PRIx64,
915 if (strchr(
"RICE", cat)) {
916 fprintf(stderr,
" align=0x%08"PRIx64, align);
922 if (villagers.size()>0) fprintf(stderr,
"%s Villagers:\n", p);
923 for (
size_t i=0; i<villagers.size(); i++) {
927 fprintf(stderr,
"%s %c %c0x%08"PRIx64
" 0x%08"PRIx64
" 0x%08"PRIx64,
938 for (
size_t i=0; i<neighbors.size(); i++) {
943 align = boost::math::lcm(align, x?x:1);
946 aligned_sa = (sa/align + (sa%align?1:0))*align;
947 aligned_sasn = ((sa+sn)/align + ((sa+sn)%align?1:0))*align;
949 fprintf(stderr,
"%s Alignment LCM = 0x%08"PRIx64
" (%"PRIu64
")\n", p, align, align);
950 fprintf(stderr,
"%s Aligned Sa = 0x%08"PRIx64
" (%"PRIu64
")\n", p, aligned_sa, aligned_sa);
951 fprintf(stderr,
"%s Aligned Sa+Sn = 0x%08"PRIx64
" (%"PRIu64
")\n", p, aligned_sasn, aligned_sasn);
956 if (0==villagers.size())
break;
959 for (
size_t i=0; i<villagers.size(); i++) {
967 ROSE_ASSERT(after_hole);
971 fprintf(stderr,
"%s hole size = 0x%08"PRIx64
" (%"PRIu64
"); need 0x%08"PRIx64
" (%"PRIu64
"); %s\n",
972 p, hole_size, hole_size, aligned_sasn, aligned_sasn,
973 hole_size>=aligned_sasn ?
"large enough" :
"not large enough");
975 if (hole_size >= aligned_sasn)
break;
980 ROSE_ASSERT(0==pass);
982 fprintf(stderr,
"%s Calling recursively to increase hole size by 0x%08"PRIx64
" (%"PRIu64
") bytes\n",
983 p, need_more, need_more);
985 shift_extend(after_hole, need_more, 0, space, elasticity);
986 if (debug) fprintf(stderr,
"%s Returned from recursive call\n", p);
990 if (debug) fprintf(stderr,
"%s -- ADJUSTING --\n", p);
991 bool resized_mem =
false;
992 for (
size_t i=0; i<neighbors.size(); i++) {
1010 if (memspace && !resized_mem && a->
is_mapped()) {
1031 if (memspace && !resized_mem && a->
is_mapped()) {
1050 if (memspace && !resized_mem && a->
is_mapped()) {
1059 ROSE_ASSERT(!
"invalid extent category");
1063 const char *space_name = filespace ?
"file" :
"mem";
1065 fprintf(stderr,
"%s %4s-%c %c0x%08"PRIx64
" 0x%08"PRIx64
" 0x%08"PRIx64,
1070 fprintf(stderr,
" -> %c0x%08"PRIx64
" 0x%08"PRIx64
" 0x%08"PRIx64,
1071 0==newap.relaxed_first()%(x?x:1)?
' ':
'!',
1072 newap.relaxed_first(), newap.size(), newap.relaxed_first()+newap.size());
1076 if (debug) fprintf(stderr,
"%s -- END --\n", p);
1088 std::string dump_name =
get_name() + ext;
1090 size_t slash = dump_name.find_last_of(
'/');
1091 if (slash!=dump_name.npos)
1092 dump_name.replace(0, slash+1,
"");
1101 FILE *dumpFile = fopen(dump_name.c_str(),
"wb");
1102 ROSE_ASSERT(dumpFile != NULL);
1112 for (
size_t i = 0; i < sections.size(); i++) {
1113 fprintf(dumpFile,
"Section [%zd]:\n", i);
1114 ROSE_ASSERT(sections[i] != NULL);
1115 sections[i]->dump(dumpFile,
" ", -1);
1119 SgBinaryComposite *binary = SageInterface::getEnclosingNode<SgBinaryComposite>(
this);
1120 ROSE_ASSERT(binary!=NULL);
1122 for (
size_t i=0; i<interps.size(); i++) {
1124 if (interp_files.size()==1 && interp_files[0]==
this) {
1125 std::string assembly = unparseAsmInterpretation(interps[i]);
1126 fputs(assembly.c_str(), dumpFile);
1144 if (sections.size()==0) {
1145 fprintf(f,
"No sections defined for file.\n");
1150 for (
size_t i = 1; i < sections.size(); i++) {
1151 for (
size_t j=0; j<i; j++) {
1152 if (sections[j]->get_offset() == sections[i]->get_offset()) {
1157 if (size_j < size_i) {
1159 sections[j] = sections[i];
1162 }
else if (sections[j]->get_offset() > sections[i]->get_offset()) {
1164 sections[j] = sections[i];
1171 fprintf(f,
"File sections:\n");
1172 fprintf(f,
" Flg File-Addr File-Size File-End Base-VA Start-RVA Virt-Size End-RVA Perm ID Name\n");
1173 fprintf(f,
" --- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---- --- -----------------\n");
1175 for (
size_t i=0; i<sections.size(); i++) {
1179 char overlap[4] =
" ";
1180 for (
size_t j=0; overlap[0]==
' ' && j<i; j++) {
1181 if (sections[j]->get_offset()+sections[j]->get_size() > section->
get_offset()) {
1185 for (
size_t j=i+1; overlap[1]==
' ' && j<sections.size(); j++) {
1192 if (high_water < section->get_offset()) {
1194 }
else if (i>0 && sections[i-1]->get_offset()+sections[i-1]->get_size() < section->
get_offset()) {
1198 fprintf(f,
" %3s", overlap);
1201 fprintf(f,
"%c0x%08"PRIx64
" 0x%08"PRIx64
" 0x%08"PRIx64,
1207 fprintf(f,
" %c0x%08"PRIx64
" 0x%08"PRIx64
" 0x%08"PRIx64
" 0x%08"PRIx64,
1213 fprintf(f,
" %*s", 4*11,
"");
1218 fprintf(f,
" %c%c%c ",
1227 if (section->
get_id()>=0) {
1228 fprintf(f,
" %3d", section->
get_id());
1235 char overlap[4] =
" ";
1238 }
else if (sections.back()->get_offset() + sections.back()->get_size() <
get_current_size()) {
1241 fprintf(f,
" %3s 0x%08"PRIx64
"%*s EOF", overlap,
get_current_size(), 76,
"");
1243 fprintf(f,
" (original EOF was 0x%08zx)",
p_data.
size());
1245 fputs(
" [ztrunc]", f);
1247 fprintf(f,
" --- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---- --- -----------------\n");
1251 if (holes.
size()>0) {
1252 fprintf(f,
"These parts of the file have not been referenced during parsing:\n");
1266 for (SgAsmGenericSectionPtrList::iterator i=sections.begin(); i!=sections.end(); ++i) {
1267 refs.
insert(
Extent((*i)->get_offset(), (*i)->get_size()));
1294 for (
size_t i=0; i<to_delete.size(); i++) {
1309 reallocated =
false;
1313 if ((*i)->reallocate())
1319 if ((*i)->reallocate())
1322 }
while (reallocated);
1334 f <<
"NOTE: ROSE is refusing to create a binary file for this AST.\n"
1335 <<
" See SgAsmGenericFile::set_neuter() for details.\n";
1343 unsigned char buf[4096];
1344 memset(buf, 0xaa,
sizeof buf);
1345 while (remaining>=
sizeof buf) {
1346 f.write((
const char*)buf,
sizeof buf);
1348 remaining -=
sizeof buf;
1350 f.write((
const char*)buf, remaining);
1373 f.seekp(0, std::ios::end);
1376 const char zero =
'\0';
1397 ROSE_ASSERT(NULL == retval);