10 #include "definition_dcls.h"
11 #include "object_map.h"
14 uint64_t *load_segment(const char *path, int *bitcount) {
15 int fd = open(path, O_RDONLY);
17 fprintf(stderr, "can't find segment at %s\n", path);
21 uint64_t *segment = (uint64_t *)mmap(
23 01000000 * sizeof(uint64_t),
29 rassert(segment != (uint64_t *)-1);
32 rassert(fstat(fd, &stat_buf) != -1);
37 for (; i && path[i - 1] != '/'; --i)
39 const char *name = path + i;
41 char path_dir[0x1000];
42 rassert(i + 4 < sizeof(path_dir));
43 memcpy(path_dir, path, i);
44 strcpy(path_dir + i, ".dir");
46 FILE *fp = fopen(path_dir, "r");
48 fprintf(stderr, "can't find index %s\n", path_dir);
52 while (fgets(line, 0x100, fp)) {
53 char *p = strchr(line, ' ');
56 if (strcmp(line, name) == 0) {
58 *bitcount = (int)strtol(p, NULL, 0);
65 fprintf(stderr, "can't find segment name %s in index %s\n", name, path_dir);
69 if (*bitcount > (stat_buf.st_size / sizeof(uint64_t)) * 36) {
72 "file size %ld bytes too short for bitcount %d\n",
82 struct object_map *get_object_map(uint64_t *segment, int bitcount) {
83 if (bitcount % 36 != 0) {
84 fprintf(stderr, "bitcount %d not multiple of 36\n", bitcount);
88 int wordcount = (bitcount / 36) & 0777777;
90 fprintf(stderr, "wordcount %d too short\n", wordcount);
94 int object_map_offset = (segment[wordcount - 1] >> 18) & 0777777;
96 object_map_offset + sizeof(struct object_map) / sizeof(uint64_t) + 1 >
99 printf("bad object map offset\n");
103 struct object_map *object_map = (struct object_map *)(
104 segment + object_map_offset
107 object_map->decl_vers != 2 ||
108 object_map->identifier[0] != 0157142152137 || // 'obj_'
109 object_map->identifier[1] != 0155141160040 // 'map '
111 fprintf(stderr, "bad object map signature\n");
118 void get_acc_string(uint64_t *acc_string, char *buf, int buf_len) {
119 int len = (acc_string[0] >> 27) & 0777;
120 rassert(len < buf_len);
122 static int shifts[4] = {27, 18, 9, 0};
123 for (int i = 0, j = 1; i < len; ++i, ++j)
124 buf[i] = (char)(acc_string[j >> 2] >> shifts[j & 3]);
128 void dump_segments(uint64_t *segment, int bitcount) {
129 struct object_map *object_map = get_object_map(segment, bitcount);
130 struct definition_header *definition_header = (struct definition_header *)(
131 segment + object_map->definition_offset
135 struct segname_definition *segname_definition =
136 (struct segname_definition *)(
137 (uint64_t *)definition_header + definition_header->def_list_relp
139 *(uint64_t *)segname_definition;
140 segname_definition = (struct segname_definition *)(
141 (uint64_t *)definition_header + segname_definition->next_segname_relp
144 rassert(segname_definition->class == CLASS_SEGNAME);
148 (uint64_t *)definition_header + segname_definition->name_relp,
152 printf("%s\n", name);
156 int main(int argc, char **argv) {
159 "usage: %s path_to_segment\n",
166 uint64_t *segment = load_segment(argv[1], &bitcount);
167 dump_segments(segment, bitcount);