7 #include "hunk-reloc.h"
10 //#define DEBUG printf
12 #define READLW(a, b) fread(&a, 4, 1, b); a = be32toh(a);
13 #define READW(a, b) fread(&a, 2, 1, b); a = be16toh(a);
17 char *hunk_id_name(uint32_t index) {
23 case HUNKTYPE_HUNK_RELOC32:
24 return "HUNK_RELOC32";
34 return "UNKNOWN HUNK TYPE";
38 int process_hunk(uint32_t index, struct hunk_info *info, FILE *f, struct hunk_reloc *r) {
42 uint32_t discard = 0, cur_hunk = 0, offs32 = 0;
46 DEBUG("Processing hunk header.\n");
50 info->libnames[info->num_libs] = malloc(discard * 4);
51 fread(info->libnames[info->num_libs], discard, 4, f);
56 READLW(info->table_size, f);
57 DEBUG("Table size: %d\n", info->table_size);
58 READLW(info->first_hunk, f);
59 READLW(info->last_hunk, f);
60 info->num_hunks = (info->last_hunk - info->first_hunk) + 1;
61 DEBUG("First: %d Last: %d Num: %d\n", info->first_hunk, info->last_hunk, info->num_hunks);
62 info->hunk_sizes = malloc(info->num_hunks * 4);
63 info->hunk_offsets = malloc(info->num_hunks * 4);
64 for (uint32_t i = 0; i < info->table_size; i++) {
65 READLW(info->hunk_sizes[i], f);
66 DEBUG("Hunk %d: %d (%.8X)\n", i, info->hunk_sizes[i] * 4, info->hunk_sizes[i] * 4);
71 DEBUG("Hunk %d: CODE.\n", info->current_hunk);
73 info->hunk_offsets[info->current_hunk] = ftell(f);
74 DEBUG("Code hunk size: %d (%.8X)\n", discard * 4, discard * 4);
75 fseek(f, discard * 4, SEEK_CUR);
78 case HUNKTYPE_HUNK_RELOC32:
79 DEBUG("Hunk %d: RELOC32.\n", info->current_hunk);
80 DEBUG("Processing Reloc32 hunk.\n");
85 DEBUG("Relocating %d offsets pointing to hunk %d.\n", discard, cur_hunk);
86 for(uint32_t i = 0; i < discard; i++) {
88 DEBUG("#%d: @%.8X in hunk %d\n", i + 1, offs32, cur_hunk);
89 r[info->reloc_hunks].offset = offs32;
90 r[info->reloc_hunks].src_hunk = info->current_hunk;
91 r[info->reloc_hunks].target_hunk = cur_hunk;
99 DEBUG("Hunk %d: SYMBOL.\n", info->current_hunk);
100 DEBUG("Processing Symbol hunk.\n");
105 memset(sstr, 0x00, 256);
106 fread(sstr, discard, 4, f);
108 DEBUG("Symbol: %s - %.8X\n", sstr, discard);
115 DEBUG("Hunk %d: BSS.\n", info->current_hunk);
117 info->hunk_offsets[info->current_hunk] = ftell(f);
118 DEBUG("Skipping BSS hunk. Size: %d\n", discard * 4);
121 DEBUG("Hunk %d: DATA.\n", info->current_hunk);
123 info->hunk_offsets[info->current_hunk] = ftell(f);
124 DEBUG("Skipping data hunk. Size: %d.\n", discard * 4);
125 fseek(f, discard * 4, SEEK_CUR);
129 DEBUG("END: Ending hunk %d.\n", info->current_hunk);
130 info->current_hunk++;
134 DEBUG("Unknown hunk type %.8X! Can't process!\n", index);
141 void reloc_hunk(struct hunk_reloc *h, uint8_t *buf, struct hunk_info *i) {
142 uint32_t rel = i->hunk_offsets[h->target_hunk];
143 uint32_t *src_ptr = (uint32_t *)(&buf[i->hunk_offsets[h->src_hunk] + h->offset]);
145 uint32_t src = be32toh(*src_ptr);
146 uint32_t dst = src + i->base_offset + rel;
147 DEBUG("%.8X -> %.8X\n", src, dst);
148 *src_ptr = htobe32(dst);
151 void process_hunks(FILE *in, struct hunk_info *h_info, struct hunk_reloc *r) {
153 DEBUG("Hunk ID: %.8X (%s)\n", lw, hunk_id_name(lw));
155 while(!feof(in) && process_hunk(lw, h_info, in, r) != -1) {
157 if (feof(in)) goto end_parse;
158 DEBUG("Hunk ID: %.8X (%s)\n", lw, hunk_id_name(lw));
159 DEBUG("File pos: %.8lX\n", ftell(in));
162 DEBUG("Done processing hunks.\n");
165 void reloc_hunks(struct hunk_reloc *r, uint8_t *buf, struct hunk_info *h_info) {
166 for(uint32_t i = 0; i < h_info->reloc_hunks; i++) {
167 reloc_hunk(&r[i], buf, h_info);
168 DEBUG("Relocating offset %d.\n", i);
170 DEBUG("Done relocating offsets.\n");