section.c (2606B)
1 #include <assert.h> 2 #include <errno.h> 3 #include <limits.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 8 #include <scc/mach.h> 9 #include <scc/scc.h> 10 11 #include "ld.h" 12 13 #define NR_SECTION 32 14 15 /* 16 * struct sectab has a Section as first field because 17 * the code is going to cast from the sections to the tab. 18 */ 19 struct sectab { 20 Section sec; 21 FILE *tmpfp; 22 struct sectab *hash; 23 struct sectab *next; 24 }; 25 26 static struct sectab *sectab[NR_SECTION]; 27 static struct sectab *secs; 28 29 Section * 30 lookupsec(char *name) 31 { 32 unsigned h; 33 size_t len; 34 char *s; 35 Section *sec; 36 struct sectab *sp; 37 38 h = genhash(name) % NR_SECTION; 39 for (sp = sectab[h]; sp; sp = sp->hash) { 40 if (!strcmp(name, sp->sec.name)) 41 return &sp->sec; 42 } 43 44 len = strlen(name) + 1; 45 s = malloc(len); 46 sp = malloc(sizeof(*sp)); 47 if (!s || !sp) { 48 error(strerror(errno)); 49 exit(EXIT_FAILURE); 50 } 51 52 sec = &sp->sec; 53 sec->name = memcpy(s, name, len); 54 sec->type = 'U'; 55 sec->base = 0; 56 sec->size = 0; 57 sec->align = 0; 58 sec->index = 0; 59 sec->flags = 0; 60 sp->tmpfp = NULL; 61 sp->hash = sectab[h]; 62 sectab[h] = sp; 63 sp->next = secs; 64 secs = sp; 65 66 return sec; 67 } 68 69 void 70 merge(Segment *seg) 71 { 72 struct sectab *sp; 73 Section *sec, **p; 74 int n = 0; 75 76 for (sp = secs; sp; sp = sp->next) { 77 sec = &sp->sec; 78 if (sec->type != seg->type) 79 continue; 80 p = realloc(seg->sections, (n+1) * sizeof(*p)); 81 if (!p) { 82 error("out of memory"); 83 exit(EXIT_FAILURE); 84 } 85 p[n++] = sec; 86 seg->sections = p; 87 88 /* rebase(obj, sec->index, seg->size); */ 89 seg->size += sec->size; 90 } 91 92 seg->nsec = n; 93 } 94 95 static FILE * 96 mkfile(Section *sec, unsigned long long size) 97 { 98 struct sectab *sp = (struct sectab *) sec; 99 100 if (sec->size > ULLONG_MAX - size) { 101 error("%s: section too long", sec->name); 102 exit(EXIT_FAILURE); 103 } 104 sec->size += size; 105 106 if (!sp->tmpfp && (sp->tmpfp = tmpfile()) == NULL) { 107 error(strerror(errno)); 108 exit(EXIT_FAILURE); 109 } 110 111 return sp->tmpfp; 112 } 113 114 void 115 copy(Obj *obj, Section *osec, Section *sec) 116 { 117 FILE *fp; 118 119 fp = mkfile(sec, osec->size); 120 /* 121 if (mapsec(obj, osec->index, fp) < 0) { 122 error(strerror(errno)); 123 return; 124 } 125 */ 126 } 127 128 void 129 grow(Section *sec, int nbytes) 130 { 131 FILE *fp; 132 133 fp = mkfile(sec, nbytes); 134 while (nbytes-- > 0) 135 putc(0, fp); 136 } 137 138 #ifndef NDEBUG 139 void 140 debugsec(void) 141 { 142 struct sectab **spp, *sp; 143 Section *sec; 144 145 fputs("Sections:\n", stderr); 146 for (spp = sectab; spp < §ab[NR_SECTION]; spp++) { 147 for (sp = *spp; sp; sp = sp->hash) { 148 sec = &sp->sec; 149 fprintf(stderr, 150 "sec: %s - %c (%#llx,%#lx)\n", 151 sec->name, 152 sec->type, 153 sec->base, 154 sec->size); 155 } 156 } 157 } 158 #endif