mirror of
https://github.com/golang/go
synced 2024-11-22 22:00:02 -07:00
cmd/ld: add -B option to set build ID
Background on build ID: http://fedoraproject.org/wiki/RolandMcGrath/BuildID R=rsc CC=golang-dev https://golang.org/cl/6625072
This commit is contained in:
parent
dfc7304d32
commit
32316bba5b
@ -79,6 +79,7 @@ enum {
|
||||
ElfStrGnuVersionR,
|
||||
ElfStrNoteNetbsdIdent,
|
||||
ElfStrNoteOpenbsdIdent,
|
||||
ElfStrNoteBuildInfo,
|
||||
ElfStrNoPtrData,
|
||||
ElfStrNoPtrBss,
|
||||
NElfStr
|
||||
@ -523,6 +524,8 @@ doelf(void)
|
||||
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
|
||||
if(HEADTYPE == Hopenbsd)
|
||||
elfstr[ElfStrNoteOpenbsdIdent] = addstring(shstrtab, ".note.openbsd.ident");
|
||||
if(buildinfolen > 0)
|
||||
elfstr[ElfStrNoteBuildInfo] = addstring(shstrtab, ".note.gnu.build-id");
|
||||
addstring(shstrtab, ".rodata");
|
||||
addstring(shstrtab, ".gcdata");
|
||||
addstring(shstrtab, ".gcbss");
|
||||
@ -669,7 +672,7 @@ asmb(void)
|
||||
int a, dynsym;
|
||||
uint32 fo, symo, startva, resoff;
|
||||
ElfEhdr *eh;
|
||||
ElfPhdr *ph, *pph;
|
||||
ElfPhdr *ph, *pph, *pnote;
|
||||
ElfShdr *sh;
|
||||
Section *sect;
|
||||
int o;
|
||||
@ -706,6 +709,8 @@ asmb(void)
|
||||
}
|
||||
if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd)
|
||||
elftextsh += 1;
|
||||
if(buildinfolen > 0)
|
||||
elftextsh += 1;
|
||||
}
|
||||
|
||||
/* output symbol table */
|
||||
@ -876,6 +881,7 @@ asmb(void)
|
||||
phsh(ph, sh);
|
||||
}
|
||||
|
||||
pnote = nil;
|
||||
if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd) {
|
||||
sh = nil;
|
||||
switch(HEADTYPE) {
|
||||
@ -889,10 +895,22 @@ asmb(void)
|
||||
break;
|
||||
}
|
||||
|
||||
ph = newElfPhdr();
|
||||
ph->type = PT_NOTE;
|
||||
ph->flags = PF_R;
|
||||
phsh(ph, sh);
|
||||
pnote = newElfPhdr();
|
||||
pnote->type = PT_NOTE;
|
||||
pnote->flags = PF_R;
|
||||
phsh(pnote, sh);
|
||||
}
|
||||
|
||||
if(buildinfolen > 0) {
|
||||
sh = newElfShdr(elfstr[ElfStrNoteBuildInfo]);
|
||||
resoff -= elfbuildinfo(sh, startva, resoff);
|
||||
|
||||
if(pnote == nil) {
|
||||
pnote = newElfPhdr();
|
||||
pnote->type = PT_NOTE;
|
||||
pnote->flags = PF_R;
|
||||
}
|
||||
phsh(pnote, sh);
|
||||
}
|
||||
|
||||
elfphload(&segtext);
|
||||
@ -1079,6 +1097,8 @@ asmb(void)
|
||||
a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
|
||||
if(HEADTYPE == Hopenbsd)
|
||||
a += elfwriteopenbsdsig(elfstr[ElfStrNoteOpenbsdIdent]);
|
||||
if(buildinfolen > 0)
|
||||
a += elfwritebuildinfo(elfstr[ElfStrNoteBuildInfo]);
|
||||
if(a > ELFRESERVE)
|
||||
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
|
||||
break;
|
||||
|
@ -143,6 +143,10 @@ main(int argc, char *argv[])
|
||||
val = EARGF(usage());
|
||||
addstrdata(name, val);
|
||||
break;
|
||||
case 'B':
|
||||
val = EARGF(usage());
|
||||
addbuildinfo(val);
|
||||
break;
|
||||
} ARGEND
|
||||
|
||||
USED(argc);
|
||||
|
@ -96,6 +96,7 @@ enum {
|
||||
ElfStrGnuVersionR,
|
||||
ElfStrNoteNetbsdIdent,
|
||||
ElfStrNoteOpenbsdIdent,
|
||||
ElfStrNoteBuildInfo,
|
||||
ElfStrNoPtrData,
|
||||
ElfStrNoPtrBss,
|
||||
NElfStr
|
||||
@ -597,6 +598,8 @@ doelf(void)
|
||||
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
|
||||
if(HEADTYPE == Hopenbsd)
|
||||
elfstr[ElfStrNoteOpenbsdIdent] = addstring(shstrtab, ".note.openbsd.ident");
|
||||
if(buildinfolen > 0)
|
||||
elfstr[ElfStrNoteBuildInfo] = addstring(shstrtab, ".note.gnu.build-id");
|
||||
addstring(shstrtab, ".elfdata");
|
||||
addstring(shstrtab, ".rodata");
|
||||
addstring(shstrtab, ".gcdata");
|
||||
@ -734,7 +737,7 @@ asmb(void)
|
||||
int a, dynsym;
|
||||
vlong vl, startva, symo, dwarfoff, machlink, resoff;
|
||||
ElfEhdr *eh;
|
||||
ElfPhdr *ph, *pph;
|
||||
ElfPhdr *ph, *pph, *pnote;
|
||||
ElfShdr *sh;
|
||||
Section *sect;
|
||||
Sym *sym;
|
||||
@ -807,6 +810,8 @@ asmb(void)
|
||||
}
|
||||
if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd)
|
||||
elftextsh += 1;
|
||||
if(buildinfolen > 0)
|
||||
elftextsh += 1;
|
||||
break;
|
||||
case Hwindows:
|
||||
break;
|
||||
@ -976,6 +981,7 @@ asmb(void)
|
||||
phsh(ph, sh);
|
||||
}
|
||||
|
||||
pnote = nil;
|
||||
if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd) {
|
||||
sh = nil;
|
||||
switch(HEADTYPE) {
|
||||
@ -989,10 +995,22 @@ asmb(void)
|
||||
break;
|
||||
}
|
||||
|
||||
ph = newElfPhdr();
|
||||
ph->type = PT_NOTE;
|
||||
ph->flags = PF_R;
|
||||
phsh(ph, sh);
|
||||
pnote = newElfPhdr();
|
||||
pnote->type = PT_NOTE;
|
||||
pnote->flags = PF_R;
|
||||
phsh(pnote, sh);
|
||||
}
|
||||
|
||||
if(buildinfolen > 0) {
|
||||
sh = newElfShdr(elfstr[ElfStrNoteBuildInfo]);
|
||||
resoff -= elfbuildinfo(sh, startva, resoff);
|
||||
|
||||
if(pnote == nil) {
|
||||
pnote = newElfPhdr();
|
||||
pnote->type = PT_NOTE;
|
||||
pnote->flags = PF_R;
|
||||
}
|
||||
phsh(pnote, sh);
|
||||
}
|
||||
|
||||
elfphload(&segtext);
|
||||
@ -1179,6 +1197,8 @@ asmb(void)
|
||||
a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
|
||||
if(HEADTYPE == Hopenbsd)
|
||||
a += elfwriteopenbsdsig(elfstr[ElfStrNoteOpenbsdIdent]);
|
||||
if(buildinfolen > 0)
|
||||
a += elfwritebuildinfo(elfstr[ElfStrNoteBuildInfo]);
|
||||
if(a > ELFRESERVE)
|
||||
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
|
||||
break;
|
||||
|
@ -140,6 +140,10 @@ main(int argc, char *argv[])
|
||||
val = EARGF(usage());
|
||||
addstrdata(name, val);
|
||||
break;
|
||||
case 'B':
|
||||
val = EARGF(usage());
|
||||
addbuildinfo(val);
|
||||
break;
|
||||
} ARGEND
|
||||
|
||||
if(argc != 1)
|
||||
|
@ -92,6 +92,7 @@ enum {
|
||||
ElfStrGnuVersionR,
|
||||
ElfStrNoteNetbsdIdent,
|
||||
ElfStrNoteOpenbsdIdent,
|
||||
ElfStrNoteBuildInfo,
|
||||
ElfStrNoPtrData,
|
||||
ElfStrNoPtrBss,
|
||||
NElfStr
|
||||
@ -573,6 +574,8 @@ doelf(void)
|
||||
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
|
||||
if(HEADTYPE == Hopenbsd)
|
||||
elfstr[ElfStrNoteOpenbsdIdent] = addstring(shstrtab, ".note.openbsd.ident");
|
||||
if(buildinfolen > 0)
|
||||
elfstr[ElfStrNoteBuildInfo] = addstring(shstrtab, ".note.gnu.build-id");
|
||||
addstring(shstrtab, ".elfdata");
|
||||
addstring(shstrtab, ".rodata");
|
||||
addstring(shstrtab, ".gcdata");
|
||||
@ -710,7 +713,7 @@ asmb(void)
|
||||
int a, dynsym;
|
||||
uint32 symo, startva, dwarfoff, machlink, resoff;
|
||||
ElfEhdr *eh;
|
||||
ElfPhdr *ph, *pph;
|
||||
ElfPhdr *ph, *pph, *pnote;
|
||||
ElfShdr *sh;
|
||||
Section *sect;
|
||||
Sym *sym;
|
||||
@ -764,6 +767,8 @@ asmb(void)
|
||||
}
|
||||
if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd)
|
||||
elftextsh += 1;
|
||||
if(buildinfolen > 0)
|
||||
elftextsh += 1;
|
||||
}
|
||||
|
||||
symsize = 0;
|
||||
@ -1036,6 +1041,7 @@ asmb(void)
|
||||
phsh(ph, sh);
|
||||
}
|
||||
|
||||
pnote = nil;
|
||||
if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd) {
|
||||
sh = nil;
|
||||
switch(HEADTYPE) {
|
||||
@ -1049,10 +1055,22 @@ asmb(void)
|
||||
break;
|
||||
}
|
||||
|
||||
ph = newElfPhdr();
|
||||
ph->type = PT_NOTE;
|
||||
ph->flags = PF_R;
|
||||
phsh(ph, sh);
|
||||
pnote = newElfPhdr();
|
||||
pnote->type = PT_NOTE;
|
||||
pnote->flags = PF_R;
|
||||
phsh(pnote, sh);
|
||||
}
|
||||
|
||||
if(buildinfolen > 0) {
|
||||
sh = newElfShdr(elfstr[ElfStrNoteBuildInfo]);
|
||||
resoff -= elfbuildinfo(sh, startva, resoff);
|
||||
|
||||
if(pnote == nil) {
|
||||
pnote = newElfPhdr();
|
||||
pnote->type = PT_NOTE;
|
||||
pnote->flags = PF_R;
|
||||
}
|
||||
phsh(pnote, sh);
|
||||
}
|
||||
|
||||
// Additions to the reserved area must be above this line.
|
||||
@ -1249,6 +1267,8 @@ asmb(void)
|
||||
a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
|
||||
if(HEADTYPE == Hopenbsd)
|
||||
a += elfwriteopenbsdsig(elfstr[ElfStrNoteOpenbsdIdent]);
|
||||
if(buildinfolen > 0)
|
||||
a += elfwritebuildinfo(elfstr[ElfStrNoteBuildInfo]);
|
||||
if(a > ELFRESERVE)
|
||||
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
|
||||
break;
|
||||
|
@ -145,6 +145,10 @@ main(int argc, char *argv[])
|
||||
val = EARGF(usage());
|
||||
addstrdata(name, val);
|
||||
break;
|
||||
case 'B':
|
||||
val = EARGF(usage());
|
||||
addbuildinfo(val);
|
||||
break;
|
||||
} ARGEND
|
||||
|
||||
if(argc != 1)
|
||||
|
@ -58,5 +58,8 @@ Options new in this version:
|
||||
as displayed in the symbol table printed by "go tool nm".
|
||||
-b
|
||||
Link with race detection libraries.
|
||||
-B value
|
||||
Add a NT_GNU_BUILD_ID note when using ELF. The value
|
||||
should start with 0x and be an even number of hex digits.
|
||||
*/
|
||||
package documentation
|
||||
|
@ -31,6 +31,8 @@ struct Elfstring
|
||||
static Elfstring elfstr[100];
|
||||
static int nelfstr;
|
||||
|
||||
static char buildinfo[32];
|
||||
|
||||
/*
|
||||
Initialize the global variable that describes the ELF header. It will be updated as
|
||||
we write section and prog headers.
|
||||
@ -455,6 +457,77 @@ elfwriteopenbsdsig(vlong stridx)
|
||||
return sh->size;
|
||||
}
|
||||
|
||||
void
|
||||
addbuildinfo(char *val)
|
||||
{
|
||||
char *ov;
|
||||
int i, b, j;
|
||||
|
||||
if(val[0] != '0' || val[1] != 'x') {
|
||||
fprint(2, "%s: -B argument must start with 0x: %s\n", argv0, val);
|
||||
exits("usage");
|
||||
}
|
||||
ov = val;
|
||||
val += 2;
|
||||
i = 0;
|
||||
while(*val != '\0') {
|
||||
if(val[1] == '\0') {
|
||||
fprint(2, "%s: -B argument must have even number of digits: %s\n", argv0, ov);
|
||||
exits("usage");
|
||||
}
|
||||
b = 0;
|
||||
for(j = 0; j < 2; j++, val++) {
|
||||
b *= 16;
|
||||
if(*val >= '0' && *val <= '9')
|
||||
b += *val - '0';
|
||||
else if(*val >= 'a' && *val <= 'f')
|
||||
b += *val - 'a' + 10;
|
||||
else if(*val >= 'A' && *val <= 'F')
|
||||
b += *val - 'A' + 10;
|
||||
else {
|
||||
fprint(2, "%s: -B argument contains invalid hex digit %c: %s\n", argv0, *val, ov);
|
||||
exits("usage");
|
||||
}
|
||||
}
|
||||
if(i >= nelem(buildinfo)) {
|
||||
fprint(2, "%s: -B option too long (max %d digits): %s\n", argv0, (int)nelem(buildinfo), ov);
|
||||
exits("usage");
|
||||
}
|
||||
buildinfo[i++] = b;
|
||||
}
|
||||
buildinfolen = i;
|
||||
}
|
||||
|
||||
// Build info note
|
||||
#define ELF_NOTE_BUILDINFO_NAMESZ 4
|
||||
#define ELF_NOTE_BUILDINFO_TAG 3
|
||||
#define ELF_NOTE_BUILDINFO_NAME "GNU\0"
|
||||
|
||||
int
|
||||
elfbuildinfo(ElfShdr *sh, uint64 startva, uint64 resoff)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = ELF_NOTE_BUILDINFO_NAMESZ + rnd(buildinfolen, 4);
|
||||
return elfnote(sh, startva, resoff, n);
|
||||
}
|
||||
|
||||
int
|
||||
elfwritebuildinfo(vlong stridx)
|
||||
{
|
||||
ElfShdr *sh;
|
||||
|
||||
sh = elfwritenotehdr(stridx, ELF_NOTE_BUILDINFO_NAMESZ, buildinfolen, ELF_NOTE_BUILDINFO_TAG);
|
||||
if(sh == nil)
|
||||
return 0;
|
||||
|
||||
cwrite(ELF_NOTE_BUILDINFO_NAME, ELF_NOTE_BUILDINFO_NAMESZ);
|
||||
cwrite(buildinfo, buildinfolen);
|
||||
cwrite("\0\0\0", rnd(buildinfolen, 4) - buildinfolen);
|
||||
|
||||
return sh->size;
|
||||
}
|
||||
|
||||
extern int nelfsym;
|
||||
int elfverneed;
|
||||
|
||||
|
@ -979,6 +979,9 @@ int elfnetbsdsig(ElfShdr*, uint64, uint64);
|
||||
int elfwritenetbsdsig(vlong);
|
||||
int elfopenbsdsig(ElfShdr*, uint64, uint64);
|
||||
int elfwriteopenbsdsig(vlong);
|
||||
void addbuildinfo(char*);
|
||||
int elfbuildinfo(ElfShdr*, uint64, uint64);
|
||||
int elfwritebuildinfo(vlong);
|
||||
void elfdynhash(void);
|
||||
ElfPhdr* elfphload(Segment*);
|
||||
ElfShdr* elfshbits(Section*);
|
||||
@ -988,6 +991,7 @@ void elfaddverneed(Sym*);
|
||||
EXTERN int elfstrsize;
|
||||
EXTERN char* elfstrdat;
|
||||
EXTERN int elftextsh;
|
||||
EXTERN int buildinfolen;
|
||||
|
||||
/*
|
||||
* Total amount of space to reserve at the start of the file
|
||||
|
Loading…
Reference in New Issue
Block a user