~ubuntu-branches/ubuntu/saucy/golang/saucy

« back to all changes in this revision

Viewing changes to src/cmd/ld/go.c

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2013-07-08 05:52:37 UTC
  • mfrom: (29.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20130708055237-at01839e0hp8z3ni
Tags: 2:1.1-1ubuntu1
016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
59
59
                if(x->name[0] == name[0] && strcmp(x->name, name) == 0)
60
60
                        return x;
61
61
        x = mal(sizeof *x);
62
 
        x->name = strdup(name);
 
62
        x->name = estrdup(name);
63
63
        x->hash = ihash[h];
64
64
        ihash[h] = x;
65
65
        nimport++;
67
67
}
68
68
 
69
69
static void loadpkgdata(char*, char*, char*, int);
70
 
static void loaddynimport(char*, char*, char*, int);
71
 
static void loaddynexport(char*, char*, char*, int);
 
70
static void loadcgo(char*, char*, char*, int);
72
71
static int parsemethod(char**, char*, char**);
73
72
static int parsepkgdata(char*, char*, char**, char*, char**, char**, char**);
74
73
 
75
 
static Sym **dynexp;
76
 
 
77
74
void
78
75
ldpkg(Biobuf *f, char *pkg, int64 len, char *filename, int whence)
79
76
{
177
174
 
178
175
        loadpkgdata(filename, pkg, p0, p1 - p0);
179
176
 
180
 
        // look for dynimport section
181
 
        p0 = strstr(p1, "\n$$  // dynimport");
182
 
        if(p0 != nil) {
183
 
                p0 = strchr(p0+1, '\n');
184
 
                if(p0 == nil) {
185
 
                        fprint(2, "%s: found $$ // dynimport but no newline in %s\n", argv0, filename);
186
 
                        if(debug['u'])
187
 
                                errorexit();
188
 
                        return;
189
 
                }
190
 
                p1 = strstr(p0, "\n$$");
191
 
                if(p1 == nil)
192
 
                        p1 = strstr(p0, "\n!\n");
193
 
                if(p1 == nil) {
194
 
                        fprint(2, "%s: cannot find end of // dynimport section in %s\n", argv0, filename);
195
 
                        if(debug['u'])
196
 
                                errorexit();
197
 
                        return;
198
 
                }
199
 
                loaddynimport(filename, pkg, p0 + 1, p1 - (p0+1));
200
 
        }
201
 
 
202
 
        // look for dynexp section
203
 
        p0 = strstr(p1, "\n$$  // dynexport");
204
 
        if(p0 != nil) {
205
 
                p0 = strchr(p0+1, '\n');
206
 
                if(p0 == nil) {
207
 
                        fprint(2, "%s: found $$ // dynexporg but no newline in %s\n", argv0, filename);
208
 
                        if(debug['u'])
209
 
                                errorexit();
210
 
                        return;
211
 
                }
212
 
                p1 = strstr(p0, "\n$$");
213
 
                if(p1 == nil)
214
 
                        p1 = strstr(p0, "\n!\n");
215
 
                if(p1 == nil) {
216
 
                        fprint(2, "%s: cannot find end of // dynexporg section in %s\n", argv0, filename);
217
 
                        if(debug['u'])
218
 
                                errorexit();
219
 
                        return;
220
 
                }
221
 
                loaddynexport(filename, pkg, p0 + 1, p1 - (p0+1));
 
177
        // look for cgo section
 
178
        p0 = strstr(p1, "\n$$  // cgo");
 
179
        if(p0 != nil) {
 
180
                p0 = strchr(p0+1, '\n');
 
181
                if(p0 == nil) {
 
182
                        fprint(2, "%s: found $$ // cgo but no newline in %s\n", argv0, filename);
 
183
                        if(debug['u'])
 
184
                                errorexit();
 
185
                        return;
 
186
                }
 
187
                p1 = strstr(p0, "\n$$");
 
188
                if(p1 == nil)
 
189
                        p1 = strstr(p0, "\n!\n");
 
190
                if(p1 == nil) {
 
191
                        fprint(2, "%s: cannot find end of // cgo section in %s\n", argv0, filename);
 
192
                        if(debug['u'])
 
193
                                errorexit();
 
194
                        return;
 
195
                }
 
196
                loadcgo(filename, pkg, p0 + 1, p1 - (p0+1));
222
197
        }
223
198
}
224
199
 
228
203
        char *p, *ep, *prefix, *name, *def;
229
204
        Import *x;
230
205
 
231
 
        file = strdup(file);
 
206
        file = estrdup(file);
232
207
        p = data;
233
208
        ep = data + len;
234
209
        while(parsepkgdata(file, pkg, &p, ep, &prefix, &name, &def) > 0) {
235
210
                x = ilookup(name);
236
211
                if(x->prefix == nil) {
237
212
                        x->prefix = prefix;
238
 
                        x->def = strdup(def);
 
213
                        x->def = estrdup(def);
239
214
                        x->file = file;
240
215
                } else if(strcmp(x->prefix, prefix) != 0) {
241
216
                        fprint(2, "%s: conflicting definitions for %s\n", argv0, name);
267
242
                n++;
268
243
 
269
244
        if(n == 0)
270
 
                return strdup(t0);
 
245
                return estrdup(t0);
271
246
 
272
247
        // use malloc, not mal, so that caller can free
273
248
        w0 = malloc(strlen(t0) + strlen(pkg)*n);
409
384
        if(p == ep)
410
385
                return 0;
411
386
 
 
387
        // might be a comment about the method
 
388
        if(p + 2 < ep && strncmp(p, "//", 2) == 0)
 
389
                goto useline;
 
390
        
412
391
        // if it says "func (", it's a method
413
 
        if(p + 6 >= ep || strncmp(p, "func (", 6) != 0)
414
 
                return 0;
 
392
        if(p + 6 < ep && strncmp(p, "func (", 6) == 0)
 
393
                goto useline;
 
394
        return 0;
415
395
 
 
396
useline:
416
397
        // definition to end of line
417
398
        *methp = p;
418
399
        while(p < ep && *p != '\n')
428
409
}
429
410
 
430
411
static void
431
 
loaddynimport(char *file, char *pkg, char *p, int n)
 
412
loadcgo(char *file, char *pkg, char *p, int n)
432
413
{
433
 
        char *pend, *next, *name, *def, *p0, *lib, *q;
 
414
        char *pend, *next, *p0, *q;
 
415
        char *f[10], *local, *remote, *lib;
 
416
        int nf;
434
417
        Sym *s;
435
418
 
436
419
        USED(file);
437
420
        pend = p + n;
 
421
        p0 = nil;
438
422
        for(; p<pend; p=next) {
439
423
                next = strchr(p, '\n');
440
424
                if(next == nil)
441
425
                        next = "";
442
426
                else
443
427
                        *next++ = '\0';
444
 
                p0 = p;
445
 
                if(strncmp(p, "dynimport ", 10) != 0)
446
 
                        goto err;
447
 
                p += 10;
448
 
                name = p;
449
 
                p = strchr(name, ' ');
450
 
                if(p == nil)
451
 
                        goto err;
452
 
                while(*p == ' ')
453
 
                        p++;
454
 
                def = p;
455
 
                p = strchr(def, ' ');
456
 
                if(p == nil)
457
 
                        goto err;
458
 
                while(*p == ' ')
459
 
                        p++;
460
 
                lib = p;
461
 
 
462
 
                // successful parse: now can edit the line
463
 
                *strchr(name, ' ') = 0;
464
 
                *strchr(def, ' ') = 0;
465
 
                
466
 
                if(debug['d']) {
467
 
                        fprint(2, "%s: %s: cannot use dynamic imports with -d flag\n", argv0, file);
468
 
                        nerrors++;
469
 
                        return;
470
 
                }
471
 
                
472
 
                if(strcmp(name, "_") == 0 && strcmp(def, "_") == 0) {
473
 
                        // allow #pragma dynimport _ _ "foo.so"
474
 
                        // to force a link of foo.so.
475
 
                        havedynamic = 1;
476
 
                        adddynlib(lib);
477
 
                        continue;
478
 
                }
479
 
 
480
 
                name = expandpkg(name, pkg);
481
 
                q = strchr(def, '@');
482
 
                if(q)
483
 
                        *q++ = '\0';
484
 
                s = lookup(name, 0);
485
 
                free(name);
486
 
                if(s->type == 0 || s->type == SXREF) {
487
 
                        s->dynimplib = lib;
488
 
                        s->dynimpname = def;
489
 
                        s->dynimpvers = q;
490
 
                        s->type = SDYNIMPORT;
491
 
                        havedynamic = 1;
 
428
 
 
429
                free(p0);
 
430
                p0 = estrdup(p); // save for error message
 
431
                nf = tokenize(p, f, nelem(f));
 
432
                
 
433
                if(strcmp(f[0], "cgo_import_dynamic") == 0) {
 
434
                        if(nf < 2 || nf > 4)
 
435
                                goto err;
 
436
                        
 
437
                        local = f[1];
 
438
                        remote = local;
 
439
                        if(nf > 2)
 
440
                                remote = f[2];
 
441
                        lib = "";
 
442
                        if(nf > 3)
 
443
                                lib = f[3];
 
444
                        
 
445
                        if(debug['d']) {
 
446
                                fprint(2, "%s: %s: cannot use dynamic imports with -d flag\n", argv0, file);
 
447
                                nerrors++;
 
448
                                return;
 
449
                        }
 
450
                
 
451
                        if(strcmp(local, "_") == 0 && strcmp(remote, "_") == 0) {
 
452
                                // allow #pragma dynimport _ _ "foo.so"
 
453
                                // to force a link of foo.so.
 
454
                                havedynamic = 1;
 
455
                                adddynlib(lib);
 
456
                                continue;
 
457
                        }
 
458
 
 
459
                        local = expandpkg(local, pkg);
 
460
                        q = strchr(remote, '#');
 
461
                        if(q)
 
462
                                *q++ = '\0';
 
463
                        s = lookup(local, 0);
 
464
                        if(local != f[1])
 
465
                                free(local);
 
466
                        if(s->type == 0 || s->type == SXREF || s->type == SHOSTOBJ) {
 
467
                                s->dynimplib = lib;
 
468
                                s->extname = remote;
 
469
                                s->dynimpvers = q;
 
470
                                if(s->type != SHOSTOBJ)
 
471
                                        s->type = SDYNIMPORT;
 
472
                                havedynamic = 1;
 
473
                        }
 
474
                        continue;
 
475
                }
 
476
                
 
477
                if(strcmp(f[0], "cgo_import_static") == 0) {
 
478
                        if(nf != 2)
 
479
                                goto err;
 
480
                        local = f[1];
 
481
                        s = lookup(local, 0);
 
482
                        s->type = SHOSTOBJ;
 
483
                        s->size = 0;
 
484
                        continue;
 
485
                }
 
486
 
 
487
                if(strcmp(f[0], "cgo_export_static") == 0 || strcmp(f[0], "cgo_export_dynamic") == 0) {
 
488
                        // TODO: Remove once we know Windows is okay.
 
489
                        if(strcmp(f[0], "cgo_export_static") == 0 && HEADTYPE == Hwindows)
 
490
                                continue;
 
491
 
 
492
                        if(nf < 2 || nf > 3)
 
493
                                goto err;
 
494
                        local = f[1];
 
495
                        if(nf > 2)
 
496
                                remote = f[2];
 
497
                        else
 
498
                                remote = local;
 
499
                        local = expandpkg(local, pkg);
 
500
                        s = lookup(local, 0);
 
501
 
 
502
                        // export overrides import, for openbsd/cgo.
 
503
                        // see issue 4878.
 
504
                        if(s->dynimplib != nil) {
 
505
                                s->dynimplib = nil;
 
506
                                s->extname = nil;
 
507
                                s->dynimpvers = nil;
 
508
                                s->type = 0;
 
509
                        }
 
510
 
 
511
                        if(s->cgoexport == 0) {
 
512
                                s->extname = remote;
 
513
                                if(ndynexp%32 == 0)
 
514
                                        dynexp = erealloc(dynexp, (ndynexp+32)*sizeof dynexp[0]);
 
515
                                dynexp[ndynexp++] = s;
 
516
                        } else if(strcmp(s->extname, remote) != 0) {
 
517
                                fprint(2, "%s: conflicting cgo_export directives: %s as %s and %s\n", argv0, s->name, s->extname, remote);
 
518
                                nerrors++;
 
519
                                return;
 
520
                        }
 
521
                        if(strcmp(f[0], "cgo_export_static") == 0)
 
522
                                s->cgoexport |= CgoExportStatic;
 
523
                        else
 
524
                                s->cgoexport |= CgoExportDynamic;
 
525
                        if(local != f[1])
 
526
                                free(local);
 
527
                        continue;
 
528
                }
 
529
                
 
530
                if(strcmp(f[0], "cgo_dynamic_linker") == 0) {
 
531
                        if(nf != 2)
 
532
                                goto err;
 
533
                        
 
534
                        if(!debug['I']) { // not overridden by command line
 
535
                                if(interpreter != nil && strcmp(interpreter, f[1]) != 0) {
 
536
                                        fprint(2, "%s: conflict dynlinker: %s and %s\n", argv0, interpreter, f[1]);
 
537
                                        nerrors++;
 
538
                                        return;
 
539
                                }
 
540
                                free(interpreter);
 
541
                                interpreter = estrdup(f[1]);
 
542
                        }
 
543
                        continue;
 
544
                }
 
545
                
 
546
                if(strcmp(f[0], "cgo_ldflag") == 0) {
 
547
                        if(nf != 2)
 
548
                                goto err;
 
549
                        if(nldflag%32 == 0)
 
550
                                ldflag = erealloc(ldflag, (nldflag+32)*sizeof ldflag[0]);
 
551
                        ldflag[nldflag++] = estrdup(f[1]);
 
552
                        continue;
492
553
                }
493
554
        }
 
555
        free(p0);
494
556
        return;
495
557
 
496
558
err:
498
560
        nerrors++;
499
561
}
500
562
 
501
 
static void
502
 
loaddynexport(char *file, char *pkg, char *p, int n)
503
 
{
504
 
        char *pend, *next, *local, *elocal, *remote, *p0;
505
 
        Sym *s;
506
 
 
507
 
        USED(file);
508
 
        pend = p + n;
509
 
        for(; p<pend; p=next) {
510
 
                next = strchr(p, '\n');
511
 
                if(next == nil)
512
 
                        next = "";
513
 
                else
514
 
                        *next++ = '\0';
515
 
                p0 = p;
516
 
                if(strncmp(p, "dynexport ", 10) != 0)
517
 
                        goto err;
518
 
                p += 10;
519
 
                local = p;
520
 
                p = strchr(local, ' ');
521
 
                if(p == nil)
522
 
                        goto err;
523
 
                while(*p == ' ')
524
 
                        p++;
525
 
                remote = p;
526
 
 
527
 
                // successful parse: now can edit the line
528
 
                *strchr(local, ' ') = 0;
529
 
 
530
 
                elocal = expandpkg(local, pkg);
531
 
 
532
 
                s = lookup(elocal, 0);
533
 
                if(s->dynimplib != nil) {
534
 
                        fprint(2, "%s: symbol is both dynimport and dynexport %s\n", argv0, local);
535
 
                        nerrors++;
536
 
                }
537
 
                s->dynimpname = remote;
538
 
                s->dynexport = 1;
539
 
 
540
 
                if(ndynexp%32 == 0)
541
 
                        dynexp = realloc(dynexp, (ndynexp+32)*sizeof dynexp[0]);
542
 
                dynexp[ndynexp++] = s;
543
 
 
544
 
                if (elocal != local)
545
 
                        free(elocal);
546
 
        }
547
 
        return;
548
 
 
549
 
err:
550
 
        fprint(2, "%s: invalid dynexport line: %s\n", argv0, p0);
551
 
        nerrors++;
552
 
}
553
 
 
554
 
static int markdepth;
555
 
 
556
 
static void
557
 
marktext(Sym *s)
 
563
static Sym *markq;
 
564
static Sym *emarkq;
 
565
 
 
566
static void
 
567
mark1(Sym *s, Sym *parent)
 
568
{
 
569
        if(s == S || s->reachable)
 
570
                return;
 
571
        if(strncmp(s->name, "go.weak.", 8) == 0)
 
572
                return;
 
573
        s->reachable = 1;
 
574
        s->reachparent = parent;
 
575
        if(markq == nil)
 
576
                markq = s;
 
577
        else
 
578
                emarkq->queue = s;
 
579
        emarkq = s;
 
580
}
 
581
 
 
582
void
 
583
mark(Sym *s)
 
584
{
 
585
        mark1(s, nil);
 
586
}
 
587
 
 
588
static void
 
589
markflood(void)
558
590
{
559
591
        Auto *a;
560
592
        Prog *p;
561
 
 
562
 
        if(s == S)
563
 
                return;
564
 
        markdepth++;
565
 
        if(debug['v'] > 1)
566
 
                Bprint(&bso, "%d marktext %s\n", markdepth, s->name);
567
 
        for(a=s->autom; a; a=a->link)
568
 
                mark(a->gotype);
569
 
        for(p=s->text; p != P; p=p->link) {
570
 
                if(p->from.sym)
571
 
                        mark(p->from.sym);
572
 
                if(p->to.sym)
573
 
                        mark(p->to.sym);
 
593
        Sym *s;
 
594
        int i;
 
595
        
 
596
        for(s=markq; s!=S; s=s->queue) {
 
597
                if(s->text) {
 
598
                        if(debug['v'] > 1)
 
599
                                Bprint(&bso, "marktext %s\n", s->name);
 
600
                        for(a=s->autom; a; a=a->link)
 
601
                                mark1(a->gotype, s);
 
602
                        for(p=s->text; p != P; p=p->link) {
 
603
                                mark1(p->from.sym, s);
 
604
                                mark1(p->to.sym, s);
 
605
                        }
 
606
                }
 
607
                for(i=0; i<s->nr; i++)
 
608
                        mark1(s->r[i].sym, s);
 
609
                mark1(s->gotype, s);
 
610
                mark1(s->sub, s);
 
611
                mark1(s->outer, s);
574
612
        }
575
 
        markdepth--;
576
 
}
577
 
 
578
 
void
579
 
mark(Sym *s)
580
 
{
581
 
        int i;
582
 
 
583
 
        if(s == S || s->reachable)
584
 
                return;
585
 
        if(strncmp(s->name, "weak.", 5) == 0)
586
 
                return;
587
 
        s->reachable = 1;
588
 
        if(s->text)
589
 
                marktext(s);
590
 
        for(i=0; i<s->nr; i++)
591
 
                mark(s->r[i].sym);
592
 
        if(s->gotype)
593
 
                mark(s->gotype);
594
 
        if(s->sub)
595
 
                mark(s->sub);
596
 
        if(s->outer)
597
 
                mark(s->outer);
598
613
}
599
614
 
600
615
static char*
651
666
deadcode(void)
652
667
{
653
668
        int i;
654
 
        Sym *s, *last;
 
669
        Sym *s, *last, *p;
655
670
        Auto *z;
 
671
        Fmt fmt;
656
672
 
657
673
        if(debug['v'])
658
674
                Bprint(&bso, "%5.2f deadcode\n", cputime());
659
675
 
660
676
        mark(lookup(INITENTRY, 0));
 
677
        if(flag_shared)
 
678
                mark(lookup(LIBINITENTRY, 0));
661
679
        for(i=0; i<nelem(morename); i++)
662
680
                mark(lookup(morename[i], 0));
663
681
 
664
682
        for(i=0; i<ndynexp; i++)
665
683
                mark(dynexp[i]);
 
684
 
 
685
        markflood();
666
686
        
 
687
        // keep each beginning with 'typelink.' if the symbol it points at is being kept.
 
688
        for(s = allsym; s != S; s = s->allsym) {
 
689
                if(strncmp(s->name, "go.typelink.", 12) == 0)
 
690
                        s->reachable = s->nr==1 && s->r[0].sym->reachable;
 
691
        }
 
692
 
667
693
        // remove dead text but keep file information (z symbols).
668
694
        last = nil;
669
695
        z = nil;
690
716
                last->next = nil;
691
717
        
692
718
        for(s = allsym; s != S; s = s->allsym)
693
 
                if(strncmp(s->name, "weak.", 5) == 0) {
 
719
                if(strncmp(s->name, "go.weak.", 8) == 0) {
694
720
                        s->special = 1;  // do not lay out in data segment
695
721
                        s->reachable = 1;
696
722
                        s->hide = 1;
697
723
                }
 
724
        
 
725
        // record field tracking references
 
726
        fmtstrinit(&fmt);
 
727
        for(s = allsym; s != S; s = s->allsym) {
 
728
                if(strncmp(s->name, "go.track.", 9) == 0) {
 
729
                        s->special = 1;  // do not lay out in data segment
 
730
                        s->hide = 1;
 
731
                        if(s->reachable) {
 
732
                                fmtprint(&fmt, "%s", s->name+9);
 
733
                                for(p=s->reachparent; p; p=p->reachparent)
 
734
                                        fmtprint(&fmt, "\t%s", p->name);
 
735
                                fmtprint(&fmt, "\n");
 
736
                        }
 
737
                        s->type = SCONST;
 
738
                        s->value = 0;
 
739
                }
 
740
        }
 
741
        if(tracksym == nil)
 
742
                return;
 
743
        s = lookup(tracksym, 0);
 
744
        if(!s->reachable)
 
745
                return;
 
746
        addstrdata(tracksym, fmtstrflush(&fmt));
698
747
}
699
748
 
700
749
void
705
754
        // resolve weak references only if
706
755
        // target symbol will be in binary anyway.
707
756
        for(s = allsym; s != S; s = s->allsym) {
708
 
                if(strncmp(s->name, "weak.", 5) == 0) {
709
 
                        t = rlookup(s->name+5, s->version);
 
757
                if(strncmp(s->name, "go.weak.", 8) == 0) {
 
758
                        t = rlookup(s->name+8, s->version);
710
759
                        if(t && t->type != 0 && t->reachable) {
711
760
                                s->value = t->value;
712
761
                                s->type = t->type;
 
762
                                s->outer = t;
713
763
                        } else {
714
764
                                s->type = SCONST;
715
765
                                s->value = 0;
724
774
{
725
775
        int i;
726
776
        
 
777
        if(HEADTYPE == Hdarwin)
 
778
                return;
 
779
 
727
780
        for(i=0; i<ndynexp; i++)
728
781
                adddynsym(dynexp[i]);
729
782
}
802
855
                if(strcmp(p->path, path) == 0)
803
856
                        return p;
804
857
        p = mal(sizeof *p);
805
 
        p->path = strdup(path);
 
858
        p->path = estrdup(path);
806
859
        p->next = phash[h];
807
860
        phash[h] = p;
808
861
        p->all = pkgall;
826
879
                i->mimpby *= 2;
827
880
                if(i->mimpby == 0)
828
881
                        i->mimpby = 16;
829
 
                i->impby = realloc(i->impby, i->mimpby*sizeof i->impby[0]);
 
882
                i->impby = erealloc(i->impby, i->mimpby*sizeof i->impby[0]);
830
883
        }
831
884
        i->impby[i->nimpby++] = p;
832
885
        free(pkg);
871
924
        for(p=pkgall; p; p=p->all)
872
925
                cycle(p);
873
926
}
 
927
 
 
928
void
 
929
setlinkmode(char *arg)
 
930
{
 
931
        if(strcmp(arg, "internal") == 0)
 
932
                linkmode = LinkInternal;
 
933
        else if(strcmp(arg, "external") == 0)
 
934
                linkmode = LinkExternal;
 
935
        else if(strcmp(arg, "auto") == 0)
 
936
                linkmode = LinkAuto;
 
937
        else {
 
938
                fprint(2, "unknown link mode -linkmode %s\n", arg);
 
939
                errorexit();
 
940
        }
 
941
}