void print_section(const SECTION_HEADER *secthead, FILE *f, size_t symtab_off) { int first = 1; u32 i; printf("Section `%s' (section name symtab %d):\n", get_sym_name(secthead->s_name_idx, f, symtab_off), secthead->s_name_idx); printf("\tPhysical Address=0x%016llX\n", secthead->s_addr); printf("\tVirtual Address=0x%016llX\n", secthead->s_vaddr); printf("\tAlign=%d\n", secthead->s_align); printf("\tFlags="); if (secthead->s_flags & XDF_SECT_ABSOLUTE) printf("%sABSOLUTE", first-->0?"":"|"); if (secthead->s_flags & XDF_SECT_FLAT) printf("%sFLAT", first-->0?"":"|"); if (secthead->s_flags & XDF_SECT_BSS) printf("%sBSS", first-->0?"":"|"); if (secthead->s_flags & XDF_SECT_USE_16) printf("%sUSE16", first-->0?"":"|"); if (secthead->s_flags & XDF_SECT_USE_32) printf("%sUSE32", first-->0?"":"|"); if (secthead->s_flags & XDF_SECT_USE_64) printf("%sUSE64", first-->0?"":"|"); if (first>0) printf("None"); printf("\n\tData Offset=0x%08X\n", secthead->s_data_off); printf("\tData Size=%d\n", secthead->s_data_size); if (!(secthead->s_flags & XDF_SECT_BSS) && secthead->s_data_size > 0) { printf("\tSection Data:"); long oldpos = ftell(f); fseek(f, secthead->s_data_off, SEEK_SET); for (i=0; i<secthead->s_data_size; i++) { if (i % 16 == 0) printf("\n\t\t%08X:", i); if (i % 2 == 0) printf(" "); printf("%02X", fgetc(f)); } printf("\n"); fseek(f, oldpos, SEEK_SET); } printf("\tReloc Table Offset=0x%08X\n", secthead->s_reltab_off); printf("\tNum Relocs=%d\n", secthead->s_num_reloc); if (secthead->s_num_reloc > 0) { printf("\tRelocations:\n"); long oldpos = ftell(f); fseek(f, secthead->s_reltab_off, SEEK_SET); for (i=0; i<secthead->s_num_reloc; i++) { RELOCATION_ENTRY relocent; fread(&relocent, sizeof(relocent), 1, f); print_reloc(&relocent, f, symtab_off); } fseek(f, oldpos, SEEK_SET); } }
/* See gsmemory.h for why the argument is const and the result is not. */ ref_packed * igc_reloc_ref_ptr_nocheck(const ref_packed * prp, gc_state_t *gcst) { /* * Search forward for relocation. This algorithm is intrinsically very * inefficient; we hope eventually to replace it with a better one. */ const ref_packed *rp = prp; uint dec = 0; #ifdef ALIGNMENT_ALIASING_BUG const ref *rpref; # define RP_REF(rp) (rpref = (const ref *)rp, rpref) #else # define RP_REF(rp) ((const ref *)rp) #endif for (;;) { if (r_is_packed(rp)) { /* * Normally, an unmarked packed ref will be an * integer whose value is the amount of relocation. * However, the relocation value might have been * too large to fit. If this is the case, for * each such unmarked packed ref we pass over, * we have to decrement the final relocation. */ rputc((*rp & lp_mark ? '1' : '0')); if (!(*rp & lp_mark)) { if (*rp != pt_tag(pt_integer) + packed_max_value) { /* This is a stored relocation value. */ rputc('\n'); rp = print_reloc(prp, "ref", (const ref_packed *) ((const char *)prp - (*rp & packed_value_mask) + dec)); break; } /* * We know this is the first of an aligned block * of packed refs. Skip over the entire block, * decrementing the final relocation. */ dec += sizeof(ref_packed) * align_packed_per_ref; rp += align_packed_per_ref; } else rp++; continue; } if (!ref_type_uses_size_or_null(r_type(RP_REF(rp)))) { /* reloc is in r_size */ rputc('\n'); rp = print_reloc(prp, "ref", (const ref_packed *) (r_size(RP_REF(rp)) == 0 ? prp : (const ref_packed *)((const char *)prp - r_size(RP_REF(rp)) + dec))); break; } rputc('u'); rp += packed_per_ref; } /* Use a severely deprecated pun to remove the const property. */ { union { const ref_packed *r; ref_packed *w; } u; u.r = rp; return u.w; } #undef RP_REF }