~ubuntu-branches/ubuntu/utopic/golang/utopic

« back to all changes in this revision

Viewing changes to src/cmd/5l/obj.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include        "l.h"
35
35
#include        "../ld/lib.h"
36
36
#include        "../ld/elf.h"
 
37
#include        "../ld/dwarf.h"
37
38
#include        <ar.h>
38
39
 
39
40
#ifndef DEFAULT
47
48
   "noheader", Hnoheader,
48
49
   "risc", Hrisc,
49
50
   "plan9", Hplan9x32,
50
 
   "netbsd", Hnetbsd,
51
51
   "ixp1200", Hixp1200,
52
52
   "ipaq", Hipaq,
53
53
   "linux", Hlinux,
 
54
   "freebsd", Hfreebsd,
 
55
   "netbsd", Hnetbsd,
54
56
   0, 0
55
57
};
56
58
 
57
59
/*
58
60
 *      -Hrisc -T0x10005000 -R4         is aif for risc os
59
61
 *      -Hplan9 -T4128 -R4096           is plan9 format
60
 
 *      -Hnetbsd -T0xF0000020 -R4       is NetBSD format
61
62
 *      -Hixp1200                       is IXP1200 (raw)
62
63
 *      -Hipaq -T0xC0008010 -R1024      is ipaq
63
64
 *      -Hlinux -Tx -Rx                 is linux elf
 
65
 *      -Hfreebsd                       is freebsd elf
 
66
 *      -Hnetbsd                        is netbsd elf
64
67
 */
65
68
 
66
 
static char*
67
 
linkername[] =
68
 
{
69
 
        "runtime.softfloat",
70
 
        "math.sqrtGoC",
71
 
};
72
 
 
73
 
void
74
 
usage(void)
75
 
{
76
 
        fprint(2, "usage: 5l [-E entry] [-H head] [-I interpreter] [-L dir] [-T text] [-D data] [-R rnd] [-r path] [-o out] main.5\n");
77
 
        errorexit();
78
 
}
79
 
 
80
69
void
81
70
main(int argc, char *argv[])
82
71
{
83
 
        int c, i;
84
 
        char *p, *name, *val;
 
72
        char *p;
 
73
        Sym *s;
85
74
 
86
75
        Binit(&bso, 1, OWRITE);
87
76
        listinit();
92
81
        INITDAT = -1;
93
82
        INITRND = -1;
94
83
        INITENTRY = 0;
 
84
        LIBINITENTRY = 0;
 
85
        linkmode = LinkInternal; // TODO: LinkAuto once everything works.
95
86
        nuxiinit();
96
87
        
97
 
        p = getenv("GOARM");
98
 
        if(p != nil && strcmp(p, "5") == 0)
 
88
        p = getgoarm();
 
89
        if(p != nil)
 
90
                goarm = atoi(p);
 
91
        else
 
92
                goarm = 6;
 
93
        if(goarm == 5)
99
94
                debug['F'] = 1;
100
95
 
101
 
        ARGBEGIN {
102
 
        default:
103
 
                c = ARGC();
104
 
                if(c == 'l')
105
 
                        usage();
106
 
                if(c >= 0 && c < sizeof(debug))
107
 
                        debug[c]++;
108
 
                break;
109
 
        case 'o':
110
 
                outfile = EARGF(usage());
111
 
                break;
112
 
        case 'E':
113
 
                INITENTRY = EARGF(usage());
114
 
                break;
115
 
        case 'I':
116
 
                interpreter = EARGF(usage());
117
 
                break;
118
 
        case 'L':
119
 
                Lflag(EARGF(usage()));
120
 
                break;
121
 
        case 'T':
122
 
                INITTEXT = atolwhex(EARGF(usage()));
123
 
                break;
124
 
        case 'D':
125
 
                INITDAT = atolwhex(EARGF(usage()));
126
 
                break;
127
 
        case 'R':
128
 
                INITRND = atolwhex(EARGF(usage()));
129
 
                break;
130
 
        case 'r':
131
 
                rpath = EARGF(usage());
132
 
                break;
133
 
        case 'H':
134
 
                HEADTYPE = headtype(EARGF(usage()));
135
 
                /* do something about setting INITTEXT */
136
 
                break;
137
 
        case 'V':
138
 
                print("%cl version %s\n", thechar, getgoversion());
139
 
                errorexit();
140
 
        case 'X':
141
 
                name = EARGF(usage());
142
 
                val = EARGF(usage());
143
 
                addstrdata(name, val);
144
 
                break;
145
 
        } ARGEND
146
 
 
147
 
        USED(argc);
 
96
        flagcount("1", "use alternate profiling code", &debug['1']);
 
97
        flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo);
 
98
        flagstr("E", "sym: entry symbol", &INITENTRY);
 
99
        flagint32("D", "addr: data address", &INITDAT);
 
100
        flagcount("G", "debug pseudo-ops", &debug['G']);
 
101
        flagfn1("I", "interp: set ELF interp", setinterp);
 
102
        flagfn1("L", "dir: add dir to library path", Lflag);
 
103
        flagfn1("H", "head: header type", setheadtype);
 
104
        flagcount("K", "add stack underflow checks", &debug['K']);
 
105
        flagcount("M", "disable software div/mod", &debug['M']);
 
106
        flagcount("O", "print pc-line tables", &debug['O']);
 
107
        flagcount("P", "debug code generation", &debug['P']);
 
108
        flagint32("R", "rnd: address rounding", &INITRND);
 
109
        flagint32("T", "addr: text address", &INITTEXT);
 
110
        flagfn0("V", "print version and exit", doversion);
 
111
        flagcount("W", "disassemble input", &debug['W']);
 
112
        flagfn2("X", "name value: define string data", addstrdata);
 
113
        flagcount("Z", "clear stack frame on entry", &debug['Z']);
 
114
        flagcount("a", "disassemble output", &debug['a']);
 
115
        flagcount("c", "dump call graph", &debug['c']);
 
116
        flagcount("d", "disable dynamic executable", &debug['d']);
 
117
        flagstr("extld", "linker to run in external mode", &extld);
 
118
        flagstr("extldflags", "flags for external linker", &extldflags);
 
119
        flagcount("f", "ignore version mismatch", &debug['f']);
 
120
        flagcount("g", "disable go package data checks", &debug['g']);
 
121
        flagstr("k", "sym: set field tracking symbol", &tracksym);
 
122
        flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode);
 
123
        flagcount("n", "dump symbol table", &debug['n']);
 
124
        flagstr("o", "outfile: set output file", &outfile);
 
125
        flagcount("p", "insert profiling code", &debug['p']);
 
126
        flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath);
 
127
        flagcount("race", "enable race detector", &flag_race);
 
128
        flagcount("s", "disable symbol table", &debug['s']);
 
129
        flagstr("tmpdir", "leave temporary files in this directory", &tmpdir);
 
130
        flagcount("u", "reject unsafe packages", &debug['u']);
 
131
        flagcount("v", "print link trace", &debug['v']);
 
132
        flagcount("w", "disable DWARF generation", &debug['w']);
 
133
        flagcount("shared", "generate shared object", &flag_shared);
 
134
        // TODO: link mode flag
 
135
        
 
136
        flagparse(&argc, &argv, usage);
148
137
 
149
138
        if(argc != 1)
150
139
                usage();
151
140
 
 
141
        // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
 
142
        // Go was built; see ../../make.bash.
 
143
        if(linkmode == LinkAuto && strcmp(getgoextlinkenabled(), "0") == 0)
 
144
                linkmode = LinkInternal;
 
145
 
 
146
        if(linkmode == LinkExternal) {
 
147
                diag("only -linkmode=internal is supported");
 
148
                errorexit();
 
149
        } else if(linkmode == LinkAuto) {
 
150
                linkmode = LinkInternal;
 
151
        }
 
152
 
152
153
        libinit();
153
154
 
154
155
        if(HEADTYPE == -1)
155
 
                HEADTYPE = Hlinux;
 
156
                HEADTYPE = headtype(goos);
156
157
        switch(HEADTYPE) {
157
158
        default:
158
159
                diag("unknown -H option");
184
185
                if(INITRND == -1)
185
186
                        INITRND = 4096;
186
187
                break;
187
 
        case Hnetbsd:   /* boot for NetBSD */
188
 
                HEADR = 32L;
189
 
                if(INITTEXT == -1)
190
 
                        INITTEXT = 0xF0000020L;
191
 
                if(INITDAT == -1)
192
 
                        INITDAT = 0;
193
 
                if(INITRND == -1)
194
 
                        INITRND = 4096;
195
 
                break;
196
188
        case Hixp1200: /* boot for IXP1200 */
197
189
                HEADR = 0L;
198
190
                if(INITTEXT == -1)
212
204
                        INITRND = 1024;
213
205
                break;
214
206
        case Hlinux:    /* arm elf */
215
 
                debug['d'] = 1; // no dynamic linking
 
207
        case Hfreebsd:
 
208
        case Hnetbsd:
 
209
                debug['d'] = 0; // with dynamic linking
 
210
                tlsoffset = -8; // hardcoded number, first 4-byte word for g, and then 4-byte word for m
 
211
                                // this number is known to ../../pkg/runtime/cgo/gcc_linux_arm.c
216
212
                elfinit();
217
213
                HEADR = ELFRESERVE;
218
214
                if(INITTEXT == -1)
246
242
        cbp = buf.cbuf;
247
243
        cbc = sizeof(buf.cbuf);
248
244
 
 
245
        // embed goarm to runtime.goarm
 
246
        s = lookup("runtime.goarm", 0);
 
247
        s->dupok = 1;
 
248
        adduint8(s, goarm);
 
249
 
249
250
        addlibpath("command line", "command line", argv[0], "main");
250
251
        loadlib();
251
252
 
252
253
        // mark some functions that are only referenced after linker code editing
253
 
        // TODO(kaib): this doesn't work, the prog can't be found in runtime
254
 
        for(i=0; i<nelem(linkername); i++)
255
 
                mark(lookup(linkername[i], 0));
 
254
        if(debug['F'])
 
255
                mark(rlookup("_sfloat", 0));
256
256
        deadcode();
257
257
        if(textp == nil) {
258
258
                diag("no code");
268
268
        doelf();
269
269
        follow();
270
270
        softfloat();
271
 
        noops();
 
271
        // 5l -Z means zero the stack frame on entry.
 
272
        // This slows down function calls but can help avoid
 
273
        // false positives in garbage collection.
 
274
        if(debug['Z'])
 
275
                dozerostk();
 
276
        noops(); // generate stack split prolog, handle div/mod, etc.
272
277
        dostkcheck();
273
278
        span();
 
279
        addexport();
 
280
        // textaddress() functionality is handled in span()
274
281
        pclntab();
275
282
        symtab();
276
283
        dodata();
279
286
        reloc();
280
287
        asmb();
281
288
        undef();
 
289
        hostlink();
282
290
 
283
291
        if(debug['c'])
284
292
                print("ARM size = %d\n", armsize);
291
299
        errorexit();
292
300
}
293
301
 
 
302
static Sym*
 
303
zsym(char *pn, Biobuf *f, Sym *h[])
 
304
{       
 
305
        int o;
 
306
        
 
307
        o = BGETC(f);
 
308
        if(o == 0)
 
309
                return S;
 
310
        if(o < 0 || o >= NSYM || h[o] == nil)
 
311
                mangle(pn);
 
312
        return h[o];
 
313
}
 
314
 
294
315
static void
295
 
zaddr(Biobuf *f, Adr *a, Sym *h[])
 
316
zaddr(char *pn, Biobuf *f, Adr *a, Sym *h[])
296
317
{
297
318
        int i, c;
298
319
        int32 l;
299
320
        Sym *s;
300
321
        Auto *u;
301
322
 
302
 
        a->type = Bgetc(f);
303
 
        a->reg = Bgetc(f);
304
 
        c = Bgetc(f);
 
323
        a->type = BGETC(f);
 
324
        a->reg = BGETC(f);
 
325
        c = BGETC(f);
305
326
        if(c < 0 || c > NSYM){
306
327
                print("sym out of range: %d\n", c);
307
328
                Bputc(f, ALAST+1);
308
329
                return;
309
330
        }
310
331
        a->sym = h[c];
311
 
        a->name = Bgetc(f);
 
332
        a->name = BGETC(f);
 
333
        adrgotype = zsym(pn, f, h);
312
334
 
313
335
        if((schar)a->reg < 0 || a->reg > NREG) {
314
336
                print("register out of range %d\n", a->reg);
341
363
                break;
342
364
 
343
365
        case D_REGREG:
344
 
                a->offset = Bgetc(f);
 
366
        case D_REGREG2:
 
367
                a->offset = BGETC(f);
345
368
                break;
346
369
 
347
370
        case D_CONST2:
368
391
        if(s == S)
369
392
                return;
370
393
        i = a->name;
371
 
        if(i != D_AUTO && i != D_PARAM)
 
394
        if(i != D_AUTO && i != D_PARAM) {
 
395
                if(s && adrgotype)
 
396
                        s->gotype = adrgotype;
372
397
                return;
 
398
        }
373
399
 
374
400
        l = a->offset;
375
401
        for(u=curauto; u; u=u->link)
377
403
                if(u->type == i) {
378
404
                        if(u->aoffset > l)
379
405
                                u->aoffset = l;
 
406
                        if(adrgotype)
 
407
                                u->gotype = adrgotype;
380
408
                        return;
381
409
                }
382
410
 
386
414
        u->asym = s;
387
415
        u->aoffset = l;
388
416
        u->type = i;
 
417
        u->gotype = adrgotype;
389
418
}
390
419
 
391
420
void
414
443
        ntext = 0;
415
444
        eof = Boffset(f) + len;
416
445
        src[0] = 0;
 
446
        pn = estrdup(pn); // we keep it in Sym* references
417
447
 
418
448
newloop:
419
449
        memset(h, 0, sizeof(h));
425
455
loop:
426
456
        if(f->state == Bracteof || Boffset(f) >= eof)
427
457
                goto eof;
428
 
        o = Bgetc(f);
 
458
        o = BGETC(f);
429
459
        if(o == Beof)
430
460
                goto eof;
431
461
 
438
468
                sig = 0;
439
469
                if(o == ASIGNAME)
440
470
                        sig = Bget4(f);
441
 
                v = Bgetc(f); /* type */
442
 
                o = Bgetc(f); /* sym */
 
471
                v = BGETC(f); /* type */
 
472
                o = BGETC(f); /* sym */
443
473
                r = 0;
444
474
                if(v == D_STATIC)
445
475
                        r = version;
483
513
                                histfrogp++;
484
514
                        } else
485
515
                                collapsefrog(s);
 
516
                        dwarfaddfrag(s->value, s->name);
486
517
                }
487
518
                goto loop;
488
519
        }
489
520
 
490
521
        p = mal(sizeof(Prog));
491
522
        p->as = o;
492
 
        p->scond = Bgetc(f);
493
 
        p->reg = Bgetc(f);
 
523
        p->scond = BGETC(f);
 
524
        p->reg = BGETC(f);
494
525
        p->line = Bget4(f);
495
526
 
496
 
        zaddr(f, &p->from, h);
497
 
        zaddr(f, &p->to, h);
 
527
        zaddr(pn, f, &p->from, h);
 
528
        fromgotype = adrgotype;
 
529
        zaddr(pn, f, &p->to, h);
498
530
 
499
531
        if(p->as != ATEXT && p->as != AGLOBL && p->reg > NREG)
500
532
                diag("register out of range %A %d", p->as, p->reg);
582
614
                pc++;
583
615
                break;
584
616
 
 
617
        case ALOCALS:
 
618
                if(skip)
 
619
                        goto casedef;
 
620
                cursym->locals = p->to.offset;
 
621
                pc++;
 
622
                break;
 
623
 
 
624
        case ATYPE:
 
625
                if(skip)
 
626
                        goto casedef;
 
627
                pc++;
 
628
                goto loop;
 
629
 
585
630
        case ATEXT:
586
631
                if(cursym != nil && cursym->text) {
587
632
                        histtoauto();
611
656
                        etextp->next = s;
612
657
                else
613
658
                        textp = s;
 
659
                if(fromgotype) {
 
660
                        if(s->gotype && s->gotype != fromgotype)
 
661
                                diag("%s: type mismatch for %s", pn, s->name);
 
662
                        s->gotype = fromgotype;
 
663
                }
614
664
                etextp = s;
615
665
                p->align = 4;
616
666
                autosize = (p->to.offset+3L) & ~3L;
619
669
                s->type = STEXT;
620
670
                s->text = p;
621
671
                s->value = pc;
 
672
                s->args = p->to.offset2;
622
673
                lastp = p;
623
674
                p->pc = pc;
624
675
                pc++;
672
723
                        sprint(literal, "$%ux", ieeedtof(&p->from.ieee));
673
724
                        s = lookup(literal, 0);
674
725
                        if(s->type == 0) {
675
 
                                s->type = SBSS;
 
726
                                s->type = SRODATA;
676
727
                                adduint32(s, ieeedtof(&p->from.ieee));
677
728
                                s->reachable = 0;
678
729
                        }
694
745
                                p->from.ieee.l, p->from.ieee.h);
695
746
                        s = lookup(literal, 0);
696
747
                        if(s->type == 0) {
697
 
                                s->type = SBSS;
 
748
                                s->type = SRODATA;
698
749
                                adduint32(s, p->from.ieee.l);
699
750
                                adduint32(s, p->from.ieee.h);
700
751
                                s->reachable = 0;