~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/cmd/8l/asm.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-11-18 15:12:26 UTC
  • mfrom: (14.2.12 vivid-proposed)
  • Revision ID: package-import@ubuntu.com-20141118151226-zug7vn93mn3dtiz3
Tags: 2:1.3.2-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - Support co-installability with gccgo-go tool:
    - d/rules,golang-go.install: Rename bin/go -> bin/golang-go
    - d/golang-go.{postinst,prerm}: Install/remove /usr/bin/go using
      alternatives.
  - d/copyright: Amendments for full compiliance with copyright format.
  - d/control: Demote golang-go.tools to Suggests to support Ubuntu MIR.
  - dropped patches (now upstream):
    - d/p/issue27650045_40001_50001.diff
    - d/p/issue28050043_60001_70001.diff
    - d/p/issue54790044_100001_110001.diff

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
char openbsddynld[] = "/usr/libexec/ld.so";
43
43
char netbsddynld[] = "/usr/libexec/ld.elf_so";
44
44
char dragonflydynld[] = "/usr/libexec/ld-elf.so.2";
45
 
 
46
 
int32
47
 
entryvalue(void)
48
 
{
49
 
        char *a;
50
 
        Sym *s;
51
 
 
52
 
        a = INITENTRY;
53
 
        if(*a >= '0' && *a <= '9')
54
 
                return atolwhex(a);
55
 
        s = lookup(a, 0);
56
 
        if(s->type == 0)
57
 
                return INITTEXT;
58
 
        if(s->type != STEXT)
59
 
                diag("entry not text: %s", s->name);
60
 
        return s->value;
61
 
}
62
 
 
63
 
vlong
64
 
datoff(vlong addr)
65
 
{
66
 
        if(addr >= segdata.vaddr)
67
 
                return addr - segdata.vaddr + segdata.fileoff;
68
 
        if(addr >= segtext.vaddr)
69
 
                return addr - segtext.vaddr + segtext.fileoff;
70
 
        diag("datoff %#llx", addr);
71
 
        return 0;
72
 
}
 
45
char solarisdynld[] = "/lib/ld.so.1";
73
46
 
74
47
static int
75
48
needlib(char *name)
76
49
{
77
50
        char *p;
78
 
        Sym *s;
 
51
        LSym *s;
79
52
 
80
53
        if(*name == '\0')
81
54
                return 0;
82
55
 
83
56
        /* reuse hash code in symbol table */
84
57
        p = smprint(".dynlib.%s", name);
85
 
        s = lookup(p, 0);
 
58
        s = linklookup(ctxt, p, 0);
86
59
        free(p);
87
60
        if(s->type == 0) {
88
61
                s->type = 100;  // avoid SDATA, etc.
93
66
 
94
67
int     nelfsym = 1;
95
68
 
96
 
static void     addpltsym(Sym*);
97
 
static void     addgotsym(Sym*);
 
69
static void     addpltsym(Link*, LSym*);
 
70
static void     addgotsym(Link*, LSym*);
98
71
 
99
72
void
100
 
adddynrela(Sym *rela, Sym *s, Reloc *r)
 
73
adddynrela(LSym *rela, LSym *s, Reloc *r)
101
74
{
102
75
        USED(rela);
103
76
        USED(s);
106
79
}
107
80
 
108
81
void
109
 
adddynrel(Sym *s, Reloc *r)
 
82
adddynrel(LSym *s, Reloc *r)
110
83
{
111
 
        Sym *targ, *rel, *got;
 
84
        LSym *targ, *rel, *got;
112
85
 
113
86
        targ = r->sym;
114
 
        cursym = s;
 
87
        ctxt->cursym = s;
115
88
 
116
89
        switch(r->type) {
117
90
        default:
127
100
                        diag("unexpected R_386_PC32 relocation for dynamic symbol %s", targ->name);
128
101
                if(targ->type == 0 || targ->type == SXREF)
129
102
                        diag("unknown symbol %s in pcrel", targ->name);
130
 
                r->type = D_PCREL;
 
103
                r->type = R_PCREL;
131
104
                r->add += 4;
132
105
                return;
133
106
 
134
107
        case 256 + R_386_PLT32:
135
 
                r->type = D_PCREL;
 
108
                r->type = R_PCREL;
136
109
                r->add += 4;
137
110
                if(targ->type == SDYNIMPORT) {
138
 
                        addpltsym(targ);
139
 
                        r->sym = lookup(".plt", 0);
 
111
                        addpltsym(ctxt, targ);
 
112
                        r->sym = linklookup(ctxt, ".plt", 0);
140
113
                        r->add += targ->plt;
141
114
                }
142
115
                return;         
150
123
                                return;
151
124
                        }
152
125
                        s->p[r->off-2] = 0x8d;
153
 
                        r->type = D_GOTOFF;
 
126
                        r->type = R_GOTOFF;
154
127
                        return;
155
128
                }
156
 
                addgotsym(targ);
157
 
                r->type = D_CONST;      // write r->add during relocsym
 
129
                addgotsym(ctxt, targ);
 
130
                r->type = R_CONST;      // write r->add during relocsym
158
131
                r->sym = S;
159
132
                r->add += targ->got;
160
133
                return;
161
134
        
162
135
        case 256 + R_386_GOTOFF:
163
 
                r->type = D_GOTOFF;
 
136
                r->type = R_GOTOFF;
164
137
                return;
165
138
        
166
139
        case 256 + R_386_GOTPC:
167
 
                r->type = D_PCREL;
168
 
                r->sym = lookup(".got", 0);
 
140
                r->type = R_PCREL;
 
141
                r->sym = linklookup(ctxt, ".got", 0);
169
142
                r->add += 4;
170
143
                return;
171
144
 
172
145
        case 256 + R_386_32:
173
146
                if(targ->type == SDYNIMPORT)
174
147
                        diag("unexpected R_386_32 relocation for dynamic symbol %s", targ->name);
175
 
                r->type = D_ADDR;
 
148
                r->type = R_ADDR;
176
149
                return;
177
150
        
178
151
        case 512 + MACHO_GENERIC_RELOC_VANILLA*2 + 0:
179
 
                r->type = D_ADDR;
 
152
                r->type = R_ADDR;
180
153
                if(targ->type == SDYNIMPORT)
181
154
                        diag("unexpected reloc for dynamic symbol %s", targ->name);
182
155
                return;
183
156
        
184
157
        case 512 + MACHO_GENERIC_RELOC_VANILLA*2 + 1:
185
158
                if(targ->type == SDYNIMPORT) {
186
 
                        addpltsym(targ);
187
 
                        r->sym = lookup(".plt", 0);
 
159
                        addpltsym(ctxt, targ);
 
160
                        r->sym = linklookup(ctxt, ".plt", 0);
188
161
                        r->add = targ->plt;
189
 
                        r->type = D_PCREL;
 
162
                        r->type = R_PCREL;
190
163
                        return;
191
164
                }
192
 
                r->type = D_PCREL;
 
165
                r->type = R_PCREL;
193
166
                return;
194
167
        
195
168
        case 512 + MACHO_FAKE_GOTPCREL:
201
174
                                return;
202
175
                        }
203
176
                        s->p[r->off-2] = 0x8d;
204
 
                        r->type = D_PCREL;
 
177
                        r->type = R_PCREL;
205
178
                        return;
206
179
                }
207
 
                addgotsym(targ);
208
 
                r->sym = lookup(".got", 0);
 
180
                addgotsym(ctxt, targ);
 
181
                r->sym = linklookup(ctxt, ".got", 0);
209
182
                r->add += targ->got;
210
 
                r->type = D_PCREL;
 
183
                r->type = R_PCREL;
211
184
                return;
212
185
        }
213
186
        
216
189
                return;
217
190
 
218
191
        switch(r->type) {
219
 
        case D_PCREL:
220
 
                addpltsym(targ);
221
 
                r->sym = lookup(".plt", 0);
 
192
        case R_CALL:
 
193
        case R_PCREL:
 
194
                addpltsym(ctxt, targ);
 
195
                r->sym = linklookup(ctxt, ".plt", 0);
222
196
                r->add = targ->plt;
223
197
                return;
224
198
        
225
 
        case D_ADDR:
 
199
        case R_ADDR:
226
200
                if(s->type != SDATA)
227
201
                        break;
228
202
                if(iself) {
229
 
                        adddynsym(targ);
230
 
                        rel = lookup(".rel", 0);
231
 
                        addaddrplus(rel, s, r->off);
232
 
                        adduint32(rel, ELF32_R_INFO(targ->dynid, R_386_32));
233
 
                        r->type = D_CONST;      // write r->add during relocsym
 
203
                        adddynsym(ctxt, targ);
 
204
                        rel = linklookup(ctxt, ".rel", 0);
 
205
                        addaddrplus(ctxt, rel, s, r->off);
 
206
                        adduint32(ctxt, rel, ELF32_R_INFO(targ->dynid, R_386_32));
 
207
                        r->type = R_CONST;      // write r->add during relocsym
234
208
                        r->sym = S;
235
209
                        return;
236
210
                }
245
219
                        // just in case the C code assigns to the variable,
246
220
                        // and of course it only works for single pointers,
247
221
                        // but we only need to support cgo and that's all it needs.
248
 
                        adddynsym(targ);
249
 
                        got = lookup(".got", 0);
 
222
                        adddynsym(ctxt, targ);
 
223
                        got = linklookup(ctxt, ".got", 0);
250
224
                        s->type = got->type | SSUB;
251
225
                        s->outer = got;
252
226
                        s->sub = got->sub;
253
227
                        got->sub = s;
254
228
                        s->value = got->size;
255
 
                        adduint32(got, 0);
256
 
                        adduint32(lookup(".linkedit.got", 0), targ->dynid);
 
229
                        adduint32(ctxt, got, 0);
 
230
                        adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), targ->dynid);
257
231
                        r->type = 256;  // ignore during relocsym
258
232
                        return;
259
233
                }
260
234
                break;
261
235
        }
262
236
        
263
 
        cursym = s;
 
237
        ctxt->cursym = s;
264
238
        diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ->name, r->type, targ->type);
265
239
}
266
240
 
276
250
        default:
277
251
                return -1;
278
252
 
279
 
        case D_ADDR:
 
253
        case R_ADDR:
280
254
                if(r->siz == 4)
281
255
                        LPUT(R_386_32 | elfsym<<8);
282
256
                else
283
257
                        return -1;
284
258
                break;
285
259
 
286
 
        case D_PCREL:
 
260
        case R_CALL:
 
261
        case R_PCREL:
287
262
                if(r->siz == 4)
288
263
                        LPUT(R_386_PC32 | elfsym<<8);
289
264
                else
290
265
                        return -1;
291
266
                break;
292
267
        
293
 
        case D_TLS:
 
268
        case R_TLS_LE:
 
269
        case R_TLS_IE:
294
270
                if(r->siz == 4)
295
271
                        LPUT(R_386_TLS_LE | elfsym<<8);
296
272
                else
304
280
machoreloc1(Reloc *r, vlong sectoff)
305
281
{
306
282
        uint32 v;
307
 
        Sym *rs;
 
283
        LSym *rs;
308
284
        
309
285
        rs = r->xsym;
310
286
 
326
302
        switch(r->type) {
327
303
        default:
328
304
                return -1;
329
 
        case D_ADDR:
 
305
        case R_ADDR:
330
306
                v |= MACHO_GENERIC_RELOC_VANILLA<<28;
331
307
                break;
332
 
        case D_PCREL:
 
308
        case R_CALL:
 
309
        case R_PCREL:
333
310
                v |= 1<<24; // pc-relative bit
334
311
                v |= MACHO_GENERIC_RELOC_VANILLA<<28;
335
312
                break;
358
335
}
359
336
 
360
337
int
361
 
archreloc(Reloc *r, Sym *s, vlong *val)
 
338
archreloc(Reloc *r, LSym *s, vlong *val)
362
339
{
363
340
        USED(s);
364
341
        if(linkmode == LinkExternal)
365
342
                return -1;
366
343
        switch(r->type) {
367
 
        case D_CONST:
 
344
        case R_CONST:
368
345
                *val = r->add;
369
346
                return 0;
370
 
        case D_GOTOFF:
371
 
                *val = symaddr(r->sym) + r->add - symaddr(lookup(".got", 0));
 
347
        case R_GOTOFF:
 
348
                *val = symaddr(r->sym) + r->add - symaddr(linklookup(ctxt, ".got", 0));
372
349
                return 0;
373
350
        }
374
351
        return -1;
377
354
void
378
355
elfsetupplt(void)
379
356
{
380
 
        Sym *plt, *got;
 
357
        LSym *plt, *got;
381
358
        
382
 
        plt = lookup(".plt", 0);
383
 
        got = lookup(".got.plt", 0);
 
359
        plt = linklookup(ctxt, ".plt", 0);
 
360
        got = linklookup(ctxt, ".got.plt", 0);
384
361
        if(plt->size == 0) {
385
362
                // pushl got+4
386
 
                adduint8(plt, 0xff);
387
 
                adduint8(plt, 0x35);
388
 
                addaddrplus(plt, got, 4);
 
363
                adduint8(ctxt, plt, 0xff);
 
364
                adduint8(ctxt, plt, 0x35);
 
365
                addaddrplus(ctxt, plt, got, 4);
389
366
                
390
367
                // jmp *got+8
391
 
                adduint8(plt, 0xff);
392
 
                adduint8(plt, 0x25);
393
 
                addaddrplus(plt, got, 8);
 
368
                adduint8(ctxt, plt, 0xff);
 
369
                adduint8(ctxt, plt, 0x25);
 
370
                addaddrplus(ctxt, plt, got, 8);
394
371
 
395
372
                // zero pad
396
 
                adduint32(plt, 0);
 
373
                adduint32(ctxt, plt, 0);
397
374
                
398
375
                // assume got->size == 0 too
399
 
                addaddrplus(got, lookup(".dynamic", 0), 0);
400
 
                adduint32(got, 0);
401
 
                adduint32(got, 0);
 
376
                addaddrplus(ctxt, got, linklookup(ctxt, ".dynamic", 0), 0);
 
377
                adduint32(ctxt, got, 0);
 
378
                adduint32(ctxt, got, 0);
402
379
        }
403
380
}
404
381
 
405
382
static void
406
 
addpltsym(Sym *s)
 
383
addpltsym(Link *ctxt, LSym *s)
407
384
{
408
 
        Sym *plt, *got, *rel;
 
385
        LSym *plt, *got, *rel;
409
386
        
410
387
        if(s->plt >= 0)
411
388
                return;
412
389
 
413
 
        adddynsym(s);
 
390
        adddynsym(ctxt, s);
414
391
        
415
392
        if(iself) {
416
 
                plt = lookup(".plt", 0);
417
 
                got = lookup(".got.plt", 0);
418
 
                rel = lookup(".rel.plt", 0);
 
393
                plt = linklookup(ctxt, ".plt", 0);
 
394
                got = linklookup(ctxt, ".got.plt", 0);
 
395
                rel = linklookup(ctxt, ".rel.plt", 0);
419
396
                if(plt->size == 0)
420
397
                        elfsetupplt();
421
398
                
422
399
                // jmpq *got+size
423
 
                adduint8(plt, 0xff);
424
 
                adduint8(plt, 0x25);
425
 
                addaddrplus(plt, got, got->size);
 
400
                adduint8(ctxt, plt, 0xff);
 
401
                adduint8(ctxt, plt, 0x25);
 
402
                addaddrplus(ctxt, plt, got, got->size);
426
403
                
427
404
                // add to got: pointer to current pos in plt
428
 
                addaddrplus(got, plt, plt->size);
 
405
                addaddrplus(ctxt, got, plt, plt->size);
429
406
                
430
407
                // pushl $x
431
 
                adduint8(plt, 0x68);
432
 
                adduint32(plt, rel->size);
 
408
                adduint8(ctxt, plt, 0x68);
 
409
                adduint32(ctxt, plt, rel->size);
433
410
                
434
411
                // jmp .plt
435
 
                adduint8(plt, 0xe9);
436
 
                adduint32(plt, -(plt->size+4));
 
412
                adduint8(ctxt, plt, 0xe9);
 
413
                adduint32(ctxt, plt, -(plt->size+4));
437
414
                
438
415
                // rel
439
 
                addaddrplus(rel, got, got->size-4);
440
 
                adduint32(rel, ELF32_R_INFO(s->dynid, R_386_JMP_SLOT));
 
416
                addaddrplus(ctxt, rel, got, got->size-4);
 
417
                adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_386_JMP_SLOT));
441
418
                
442
419
                s->plt = plt->size - 16;
443
420
        } else if(HEADTYPE == Hdarwin) {
444
421
                // Same laziness as in 6l.
445
422
                
446
 
                Sym *plt;
447
 
 
448
 
                plt = lookup(".plt", 0);
449
 
 
450
 
                addgotsym(s);
451
 
 
452
 
                adduint32(lookup(".linkedit.plt", 0), s->dynid);
 
423
                LSym *plt;
 
424
 
 
425
                plt = linklookup(ctxt, ".plt", 0);
 
426
 
 
427
                addgotsym(ctxt, s);
 
428
 
 
429
                adduint32(ctxt, linklookup(ctxt, ".linkedit.plt", 0), s->dynid);
453
430
 
454
431
                // jmpq *got+size(IP)
455
432
                s->plt = plt->size;
456
433
 
457
 
                adduint8(plt, 0xff);
458
 
                adduint8(plt, 0x25);
459
 
                addaddrplus(plt, lookup(".got", 0), s->got);
 
434
                adduint8(ctxt, plt, 0xff);
 
435
                adduint8(ctxt, plt, 0x25);
 
436
                addaddrplus(ctxt, plt, linklookup(ctxt, ".got", 0), s->got);
460
437
        } else {
461
438
                diag("addpltsym: unsupported binary format");
462
439
        }
463
440
}
464
441
 
465
442
static void
466
 
addgotsym(Sym *s)
 
443
addgotsym(Link *ctxt, LSym *s)
467
444
{
468
 
        Sym *got, *rel;
 
445
        LSym *got, *rel;
469
446
        
470
447
        if(s->got >= 0)
471
448
                return;
472
449
        
473
 
        adddynsym(s);
474
 
        got = lookup(".got", 0);
 
450
        adddynsym(ctxt, s);
 
451
        got = linklookup(ctxt, ".got", 0);
475
452
        s->got = got->size;
476
 
        adduint32(got, 0);
 
453
        adduint32(ctxt, got, 0);
477
454
        
478
455
        if(iself) {
479
 
                rel = lookup(".rel", 0);
480
 
                addaddrplus(rel, got, s->got);
481
 
                adduint32(rel, ELF32_R_INFO(s->dynid, R_386_GLOB_DAT));
 
456
                rel = linklookup(ctxt, ".rel", 0);
 
457
                addaddrplus(ctxt, rel, got, s->got);
 
458
                adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_386_GLOB_DAT));
482
459
        } else if(HEADTYPE == Hdarwin) {
483
 
                adduint32(lookup(".linkedit.got", 0), s->dynid);
 
460
                adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), s->dynid);
484
461
        } else {
485
462
                diag("addgotsym: unsupported binary format");
486
463
        }
487
464
}
488
465
 
489
466
void
490
 
adddynsym(Sym *s)
 
467
adddynsym(Link *ctxt, LSym *s)
491
468
{
492
 
        Sym *d;
 
469
        LSym *d;
493
470
        int t;
494
471
        char *name;
495
472
        
499
476
        if(iself) {
500
477
                s->dynid = nelfsym++;
501
478
                
502
 
                d = lookup(".dynsym", 0);
 
479
                d = linklookup(ctxt, ".dynsym", 0);
503
480
 
504
481
                /* name */
505
482
                name = s->extname;
506
 
                adduint32(d, addstring(lookup(".dynstr", 0), name));
 
483
                adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), name));
507
484
                
508
485
                /* value */
509
486
                if(s->type == SDYNIMPORT)
510
 
                        adduint32(d, 0);
 
487
                        adduint32(ctxt, d, 0);
511
488
                else
512
 
                        addaddr(d, s);
 
489
                        addaddr(ctxt, d, s);
513
490
                
514
491
                /* size */
515
 
                adduint32(d, 0);
 
492
                adduint32(ctxt, d, 0);
516
493
        
517
494
                /* type */
518
495
                t = STB_GLOBAL << 4;
520
497
                        t |= STT_FUNC;
521
498
                else
522
499
                        t |= STT_OBJECT;
523
 
                adduint8(d, t);
524
 
                adduint8(d, 0);
 
500
                adduint8(ctxt, d, t);
 
501
                adduint8(ctxt, d, 0);
525
502
        
526
503
                /* shndx */
527
504
                if(s->type == SDYNIMPORT)
528
 
                        adduint16(d, SHN_UNDEF);
 
505
                        adduint16(ctxt, d, SHN_UNDEF);
529
506
                else {
530
507
                        switch(s->type) {
531
508
                        default:
542
519
                                t = 14;
543
520
                                break;
544
521
                        }
545
 
                        adduint16(d, t);
 
522
                        adduint16(ctxt, d, t);
546
523
                }
547
524
        } else if(HEADTYPE == Hdarwin) {
548
525
                diag("adddynsym: missed symbol %s (%s)", s->name, s->extname);
556
533
void
557
534
adddynlib(char *lib)
558
535
{
559
 
        Sym *s;
 
536
        LSym *s;
560
537
        
561
538
        if(!needlib(lib))
562
539
                return;
563
540
        
564
541
        if(iself) {
565
 
                s = lookup(".dynstr", 0);
 
542
                s = linklookup(ctxt, ".dynstr", 0);
566
543
                if(s->size == 0)
567
544
                        addstring(s, "");
568
 
                elfwritedynent(lookup(".dynamic", 0), DT_NEEDED, addstring(s, lib));
 
545
                elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib));
569
546
        } else if(HEADTYPE == Hdarwin) {
570
547
                machoadddynlib(lib);
571
548
        } else if(HEADTYPE != Hwindows) {
576
553
void
577
554
asmb(void)
578
555
{
579
 
        int32 v, magic;
 
556
        int32 magic;
580
557
        uint32 symo, dwarfoff, machlink;
581
558
        Section *sect;
582
 
        Sym *sym;
 
559
        LSym *sym;
583
560
        int i;
584
561
 
585
562
        if(debug['v'])
641
618
                default:
642
619
                        if(iself)
643
620
                                goto Elfsym;
644
 
                case Hgarbunix:
645
 
                        symo = rnd(HEADR+segtext.filelen, 8192)+segdata.filelen;
646
 
                        break;
647
 
                case Hunixcoff:
648
 
                        symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
649
 
                        break;
650
 
                case Hplan9x32:
651
 
                        symo = HEADR+segtext.filelen+segdata.filelen;
652
 
                        break;
653
 
                case Hmsdoscom:
654
 
                case Hmsdosexe:
655
 
                        debug['s'] = 1;
 
621
                case Hplan9:
656
622
                        symo = HEADR+segtext.filelen+segdata.filelen;
657
623
                        break;
658
624
                case Hdarwin:
685
651
                                        elfemitreloc();
686
652
                        }
687
653
                        break;
688
 
                case Hplan9x32:
 
654
                case Hplan9:
689
655
                        asmplan9sym();
690
656
                        cflush();
691
657
 
692
 
                        sym = lookup("pclntab", 0);
 
658
                        sym = linklookup(ctxt, "pclntab", 0);
693
659
                        if(sym != nil) {
694
660
                                lcsize = sym->np;
695
661
                                for(i=0; i < lcsize; i++)
715
681
        cseek(0L);
716
682
        switch(HEADTYPE) {
717
683
        default:
718
 
        case Hgarbunix: /* garbage */
719
 
                lputb(0x160L<<16);              /* magic and sections */
720
 
                lputb(0L);                      /* time and date */
721
 
                lputb(rnd(HEADR+segtext.filelen, 4096)+segdata.filelen);
722
 
                lputb(symsize);                 /* nsyms */
723
 
                lputb((0x38L<<16)|7L);          /* size of optional hdr and flags */
724
 
                lputb((0413<<16)|0437L);                /* magic and version */
725
 
                lputb(rnd(HEADR+segtext.filelen, 4096));        /* sizes */
726
 
                lputb(segdata.filelen);
727
 
                lputb(segdata.len - segdata.filelen);
728
 
                lputb(entryvalue());            /* va of entry */
729
 
                lputb(INITTEXT-HEADR);          /* va of base of text */
730
 
                lputb(segdata.vaddr);                   /* va of base of data */
731
 
                lputb(segdata.vaddr+segdata.filelen);           /* va of base of bss */
732
 
                lputb(~0L);                     /* gp reg mask */
733
 
                lputb(0L);
734
 
                lputb(0L);
735
 
                lputb(0L);
736
 
                lputb(0L);
737
 
                lputb(~0L);                     /* gp value ?? */
738
 
                break;
739
 
        case Hunixcoff: /* unix coff */
740
 
                /*
741
 
                 * file header
742
 
                 */
743
 
                lputl(0x0004014c);              /* 4 sections, magic */
744
 
                lputl(0);                       /* unix time stamp */
745
 
                lputl(0);                       /* symbol table */
746
 
                lputl(0);                       /* nsyms */
747
 
                lputl(0x0003001c);              /* flags, sizeof a.out header */
748
 
                /*
749
 
                 * a.out header
750
 
                 */
751
 
                lputl(0x10b);                   /* magic, version stamp */
752
 
                lputl(rnd(segtext.filelen, INITRND));   /* text sizes */
753
 
                lputl(segdata.filelen);                 /* data sizes */
754
 
                lputl(segdata.len - segdata.filelen);                   /* bss sizes */
755
 
                lputb(entryvalue());            /* va of entry */
756
 
                lputl(INITTEXT);                /* text start */
757
 
                lputl(segdata.vaddr);                   /* data start */
758
 
                /*
759
 
                 * text section header
760
 
                 */
761
 
                s8put(".text");
762
 
                lputl(HEADR);                   /* pa */
763
 
                lputl(HEADR);                   /* va */
764
 
                lputl(segtext.filelen);         /* text size */
765
 
                lputl(HEADR);                   /* file offset */
766
 
                lputl(0);                       /* relocation */
767
 
                lputl(0);                       /* line numbers */
768
 
                lputl(0);                       /* relocation, line numbers */
769
 
                lputl(0x20);                    /* flags text only */
770
 
                /*
771
 
                 * data section header
772
 
                 */
773
 
                s8put(".data");
774
 
                lputl(segdata.vaddr);                   /* pa */
775
 
                lputl(segdata.vaddr);                   /* va */
776
 
                lputl(segdata.filelen);                 /* data size */
777
 
                lputl(HEADR+segtext.filelen);           /* file offset */
778
 
                lputl(0);                       /* relocation */
779
 
                lputl(0);                       /* line numbers */
780
 
                lputl(0);                       /* relocation, line numbers */
781
 
                lputl(0x40);                    /* flags data only */
782
 
                /*
783
 
                 * bss section header
784
 
                 */
785
 
                s8put(".bss");
786
 
                lputl(segdata.vaddr+segdata.filelen);           /* pa */
787
 
                lputl(segdata.vaddr+segdata.filelen);           /* va */
788
 
                lputl(segdata.len - segdata.filelen);                   /* bss size */
789
 
                lputl(0);                       /* file offset */
790
 
                lputl(0);                       /* relocation */
791
 
                lputl(0);                       /* line numbers */
792
 
                lputl(0);                       /* relocation, line numbers */
793
 
                lputl(0x80);                    /* flags bss only */
794
 
                /*
795
 
                 * comment section header
796
 
                 */
797
 
                s8put(".comment");
798
 
                lputl(0);                       /* pa */
799
 
                lputl(0);                       /* va */
800
 
                lputl(symsize+lcsize);          /* comment size */
801
 
                lputl(HEADR+segtext.filelen+segdata.filelen);   /* file offset */
802
 
                lputl(HEADR+segtext.filelen+segdata.filelen);   /* offset of syms */
803
 
                lputl(HEADR+segtext.filelen+segdata.filelen+symsize);/* offset of line numbers */
804
 
                lputl(0);                       /* relocation, line numbers */
805
 
                lputl(0x200);                   /* flags comment only */
806
 
                break;
807
 
        case Hplan9x32: /* plan9 */
 
684
        case Hplan9:    /* plan9 */
808
685
                magic = 4*11*11+7;
809
686
                lputb(magic);           /* magic */
810
687
                lputb(segtext.filelen);                 /* sizes */
815
692
                lputb(spsize);                  /* sp offsets */
816
693
                lputb(lcsize);                  /* line offsets */
817
694
                break;
818
 
        case Hmsdoscom:
819
 
                /* MS-DOS .COM */
820
 
                break;
821
 
        case Hmsdosexe:
822
 
                /* fake MS-DOS .EXE */
823
 
                v = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
824
 
                wputl(0x5A4D);                  /* 'MZ' */
825
 
                wputl(v % 512);                 /* bytes in last page */
826
 
                wputl(rnd(v, 512)/512);         /* total number of pages */
827
 
                wputl(0x0000);                  /* number of reloc items */
828
 
                v = rnd(HEADR-(INITTEXT & 0xFFFF), 16);
829
 
                wputl(v/16);                    /* size of header */
830
 
                wputl(0x0000);                  /* minimum allocation */
831
 
                wputl(0xFFFF);                  /* maximum allocation */
832
 
                wputl(0x0000);                  /* initial ss value */
833
 
                wputl(0x0100);                  /* initial sp value */
834
 
                wputl(0x0000);                  /* complemented checksum */
835
 
                v = entryvalue();
836
 
                wputl(v);                       /* initial ip value (!) */
837
 
                wputl(0x0000);                  /* initial cs value */
838
 
                wputl(0x0000);
839
 
                wputl(0x0000);
840
 
                wputl(0x003E);                  /* reloc table offset */
841
 
                wputl(0x0000);                  /* overlay number */
842
 
                break;
843
695
        case Hdarwin:
844
696
                asmbmacho();
845
697
                break;
848
700
        case Hnetbsd:
849
701
        case Hopenbsd:
850
702
        case Hdragonfly:
 
703
        case Hnacl:
851
704
                asmbelf(symo);
852
705
                break;
853
706
        case Hwindows: