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

« back to all changes in this revision

Viewing changes to src/cmd/ld/symtab.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:
40
40
putelfstr(char *s)
41
41
{
42
42
        int off, n;
 
43
        char *p, *q;
43
44
 
44
45
        if(elfstrsize == 0 && s[0] != 0) {
45
46
                // first entry must be empty string
54
55
        off = elfstrsize;
55
56
        elfstrsize += n;
56
57
        memmove(elfstrdat+off, s, n);
 
58
        // replace "·" as ".", because DTrace cannot handle it.
 
59
        p = strstr(s, "·");
 
60
        if(p != nil) {
 
61
                p = q = elfstrdat+off;
 
62
                while (*q != '\0') {
 
63
                        if((uchar)*q == 0xc2 && (uchar)*(q+1) == 0xb7) {
 
64
                                q += 2;
 
65
                                *p++ = '.';
 
66
                                elfstrsize--;
 
67
                        } else {
 
68
                                *p++ = *q++;
 
69
                        }
 
70
                }
 
71
                *p = '\0';
 
72
        }
57
73
        return off;
58
74
}
59
75
 
86
102
static int elfbind;
87
103
 
88
104
static void
89
 
putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
 
105
putelfsym(LSym *x, char *s, int t, vlong addr, vlong size, int ver, LSym *go)
90
106
{
91
107
        int bind, type, off;
92
 
        Sym *xo;
 
108
        LSym *xo;
93
109
 
94
110
        USED(go);
95
111
        switch(t) {
109
125
        while(xo->outer != nil)
110
126
                xo = xo->outer;
111
127
        if(xo->sect == nil) {
112
 
                cursym = x;
 
128
                ctxt->cursym = x;
113
129
                diag("missing section in putelfsym");
114
130
                return;
115
131
        }
116
132
        if(xo->sect->elfsect == nil) {
117
 
                cursym = x;
 
133
                ctxt->cursym = x;
118
134
                diag("missing ELF section in putelfsym");
119
135
                return;
120
136
        }
143
159
}
144
160
 
145
161
void
146
 
putelfsectionsym(Sym* s, int shndx)
 
162
putelfsectionsym(LSym* s, int shndx)
147
163
{
148
164
        putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_SECTION, shndx, 0);
149
165
        s->elfsym = numelfsym++;
170
186
void
171
187
asmelfsym(void)
172
188
{
173
 
        Sym *s;
 
189
        LSym *s;
 
190
        char *name;
174
191
 
175
192
        // the first symbol entry is reserved
176
193
        putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_NOTYPE, 0, 0);
181
198
        genasmsym(putelfsym);
182
199
        
183
200
        if(linkmode == LinkExternal && HEADTYPE != Hopenbsd) {
184
 
                s = lookup("runtime.tlsgm", 0);
 
201
                s = linklookup(ctxt, "runtime.tlsgm", 0);
185
202
                if(s->sect == nil) {
186
 
                        cursym = nil;
 
203
                        ctxt->cursym = nil;
187
204
                        diag("missing section for %s", s->name);
188
205
                        errorexit();
189
206
                }
195
212
        elfglobalsymndx = numelfsym;
196
213
        genasmsym(putelfsym);
197
214
        
198
 
        for(s=allsym; s!=S; s=s->allsym) {
199
 
                if(s->type != SHOSTOBJ)
 
215
        for(s=ctxt->allsym; s!=S; s=s->allsym) {
 
216
                if(s->type != SHOSTOBJ && !(s->type == SDYNIMPORT && s->reachable))
200
217
                        continue;
201
 
                putelfsyment(putelfstr(s->name), 0, 0, (STB_GLOBAL<<4)|STT_NOTYPE, 0, 0);
 
218
                if(s->type == SDYNIMPORT)
 
219
                        name = s->extname;
 
220
                else
 
221
                        name = s->name;
 
222
                putelfsyment(putelfstr(name), 0, 0, (STB_GLOBAL<<4)|STT_NOTYPE, 0, 0);
202
223
                s->elfsym = numelfsym++;
203
224
        }
204
225
}
205
226
 
206
227
static void
207
 
putplan9sym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
 
228
putplan9sym(LSym *x, char *s, int t, vlong addr, vlong size, int ver, LSym *go)
208
229
{
209
230
        int i, l;
210
231
 
226
247
        case 'Z':
227
248
        case 'm':
228
249
                l = 4;
229
 
                if(HEADTYPE == Hplan9x64 && !debug['8']) {
 
250
                if(HEADTYPE == Hplan9 && thechar == '6' && !debug['8']) {
230
251
                        lputb(addr>>32);
231
252
                        l = 8;
232
253
                }
263
284
        genasmsym(putplan9sym);
264
285
}
265
286
 
266
 
static Sym *symt;
267
 
 
268
 
static void
269
 
scput(int b)
270
 
{
271
 
        uchar *p;
272
 
 
273
 
        symgrow(symt, symt->size+1);
274
 
        p = symt->p + symt->size;
275
 
        *p = b;
276
 
        symt->size++;
277
 
}
278
 
 
279
 
static void
280
 
slputb(int32 v)
281
 
{
282
 
        uchar *p;
283
 
 
284
 
        symgrow(symt, symt->size+4);
285
 
        p = symt->p + symt->size;
286
 
        *p++ = v>>24;
287
 
        *p++ = v>>16;
288
 
        *p++ = v>>8;
289
 
        *p = v;
290
 
        symt->size += 4;
291
 
}
292
 
 
293
 
static void
294
 
slputl(int32 v)
295
 
{
296
 
        uchar *p;
297
 
 
298
 
        symgrow(symt, symt->size+4);
299
 
        p = symt->p + symt->size;
300
 
        *p++ = v;
301
 
        *p++ = v>>8;
302
 
        *p++ = v>>16;
303
 
        *p = v>>24;
304
 
        symt->size += 4;
305
 
}
306
 
 
307
 
static void (*slput)(int32);
 
287
static LSym *symt;
308
288
 
309
289
void
310
290
wputl(ushort w)
352
332
        lputl(v >> 32);
353
333
}
354
334
 
355
 
// Emit symbol table entry.
356
 
// The table format is described at the top of ../../pkg/runtime/symtab.c.
357
 
void
358
 
putsymb(Sym *s, char *name, int t, vlong v, vlong size, int ver, Sym *typ)
359
 
{
360
 
        int i, f, c;
361
 
        vlong v1;
362
 
        Reloc *rel;
363
 
 
364
 
        USED(size);
365
 
 
366
 
        // type byte
367
 
        if('A' <= t && t <= 'Z')
368
 
                c = t - 'A' + (ver ? 26 : 0);
369
 
        else if('a' <= t && t <= 'z')
370
 
                c = t - 'a' + 26;
371
 
        else {
372
 
                diag("invalid symbol table type %c", t);
373
 
                errorexit();
374
 
                return;
375
 
        }
376
 
        
377
 
        if(s != nil)
378
 
                c |= 0x40; // wide value
379
 
        if(typ != nil)
380
 
                c |= 0x80; // has go type
381
 
        scput(c);
382
 
 
383
 
        // value
384
 
        if(s != nil) {
385
 
                // full width
386
 
                rel = addrel(symt);
387
 
                rel->siz = PtrSize;
388
 
                rel->sym = s;
389
 
                rel->type = D_ADDR;
390
 
                rel->off = symt->size;
391
 
                if(PtrSize == 8)
392
 
                        slput(0);
393
 
                slput(0);
394
 
        } else {
395
 
                // varint
396
 
                if(v < 0) {
397
 
                        diag("negative value in symbol table: %s %lld", name, v);
398
 
                        errorexit();
399
 
                }
400
 
                v1 = v;
401
 
                while(v1 >= 0x80) {
402
 
                        scput(v1 | 0x80);
403
 
                        v1 >>= 7;
404
 
                }
405
 
                scput(v1);
406
 
        }
407
 
 
408
 
        // go type if present
409
 
        if(typ != nil) {
410
 
                if(!typ->reachable)
411
 
                        diag("unreachable type %s", typ->name);
412
 
                rel = addrel(symt);
413
 
                rel->siz = PtrSize;
414
 
                rel->sym = typ;
415
 
                rel->type = D_ADDR;
416
 
                rel->off = symt->size;
417
 
                if(PtrSize == 8)
418
 
                        slput(0);
419
 
                slput(0);
420
 
        }
421
 
        
422
 
        // name 
423
 
        if(t == 'f')
424
 
                name++;
425
 
 
426
 
        if(t == 'Z' || t == 'z') {
427
 
                scput(name[0]);
428
 
                for(i=1; name[i] != 0 || name[i+1] != 0; i += 2) {
429
 
                        scput(name[i]);
430
 
                        scput(name[i+1]);
431
 
                }
432
 
                scput(0);
433
 
                scput(0);
434
 
        } else {
435
 
                for(i=0; name[i]; i++)
436
 
                        scput(name[i]);
437
 
                scput(0);
438
 
        }
439
 
 
440
 
        if(debug['n']) {
441
 
                if(t == 'z' || t == 'Z') {
442
 
                        Bprint(&bso, "%c %.8llux ", t, v);
443
 
                        for(i=1; name[i] != 0 || name[i+1] != 0; i+=2) {
444
 
                                f = ((name[i]&0xff) << 8) | (name[i+1]&0xff);
445
 
                                Bprint(&bso, "/%x", f);
446
 
                        }
447
 
                        Bprint(&bso, "\n");
448
 
                        return;
449
 
                }
450
 
                if(ver)
451
 
                        Bprint(&bso, "%c %.8llux %s<%d> %s\n", t, v, name, ver, typ ? typ->name : "");
452
 
                else
453
 
                        Bprint(&bso, "%c %.8llux %s %s\n", t, v, name, typ ? typ->name : "");
454
 
        }
455
 
}
456
 
 
457
335
void
458
336
symtab(void)
459
337
{
460
 
        Sym *s, *symtype, *symtypelink, *symgostring, *symgofunc;
 
338
        LSym *s, *symtype, *symtypelink, *symgostring, *symgofunc;
461
339
 
462
340
        dosymtype();
463
341
 
482
360
        xdefine("esymtab", SRODATA, 0);
483
361
 
484
362
        // garbage collection symbols
485
 
        s = lookup("gcdata", 0);
 
363
        s = linklookup(ctxt, "gcdata", 0);
486
364
        s->type = SRODATA;
487
365
        s->size = 0;
488
366
        s->reachable = 1;
489
367
        xdefine("egcdata", SRODATA, 0);
490
368
 
491
 
        s = lookup("gcbss", 0);
 
369
        s = linklookup(ctxt, "gcbss", 0);
492
370
        s->type = SRODATA;
493
371
        s->size = 0;
494
372
        s->reachable = 1;
495
373
        xdefine("egcbss", SRODATA, 0);
496
374
 
497
375
        // pseudo-symbols to mark locations of type, string, and go string data.
498
 
        s = lookup("type.*", 0);
 
376
        s = linklookup(ctxt, "type.*", 0);
499
377
        s->type = STYPE;
500
378
        s->size = 0;
501
379
        s->reachable = 1;
502
380
        symtype = s;
503
381
 
504
 
        s = lookup("go.string.*", 0);
 
382
        s = linklookup(ctxt, "go.string.*", 0);
505
383
        s->type = SGOSTRING;
506
384
        s->size = 0;
507
385
        s->reachable = 1;
508
386
        symgostring = s;
509
387
        
510
 
        s = lookup("go.func.*", 0);
 
388
        s = linklookup(ctxt, "go.func.*", 0);
511
389
        s->type = SGOFUNC;
512
390
        s->size = 0;
513
391
        s->reachable = 1;
514
392
        symgofunc = s;
515
393
        
516
 
        symtypelink = lookup("typelink", 0);
 
394
        symtypelink = linklookup(ctxt, "typelink", 0);
517
395
 
518
 
        symt = lookup("symtab", 0);
 
396
        symt = linklookup(ctxt, "symtab", 0);
519
397
        symt->type = SSYMTAB;
520
398
        symt->size = 0;
521
399
        symt->reachable = 1;
524
402
        // within a type they sort by size, so the .* symbols
525
403
        // just defined above will be first.
526
404
        // hide the specific symbols.
527
 
        for(s = allsym; s != S; s = s->allsym) {
 
405
        for(s = ctxt->allsym; s != S; s = s->allsym) {
528
406
                if(!s->reachable || s->special || s->type != SRODATA)
529
407
                        continue;
530
408
                if(strncmp(s->name, "type.", 5) == 0) {
547
425
                        s->hide = 1;
548
426
                        s->outer = symgofunc;
549
427
                }
550
 
        }
551
 
 
552
 
        if(debug['s'])
553
 
                return;
554
 
 
555
 
        switch(thechar) {
556
 
        default:
557
 
                diag("unknown architecture %c", thechar);
558
 
                errorexit();
559
 
        case '5':
560
 
        case '6':
561
 
        case '8':
562
 
                // little-endian symbol table
563
 
                slput = slputl;
564
 
                break;
565
 
        case 'v':
566
 
                // big-endian symbol table
567
 
                slput = slputb;
568
 
                break;
569
 
        }
570
 
        // new symbol table header.
571
 
        slput(0xfffffffd);
572
 
        scput(0);
573
 
        scput(0);
574
 
        scput(0);
575
 
        scput(PtrSize);
576
 
 
577
 
        genasmsym(putsymb);
 
428
                if(strncmp(s->name, "gcargs.", 7) == 0 || strncmp(s->name, "gclocals.", 9) == 0 || strncmp(s->name, "gclocals·", 10) == 0) {
 
429
                        s->type = SGOFUNC;
 
430
                        s->hide = 1;
 
431
                        s->outer = symgofunc;
 
432
                        s->align = 4;
 
433
                        liveness += (s->size+s->align-1)&~(s->align-1);
 
434
                }
 
435
        }
578
436
}