From patchwork Tue Jan 23 04:44:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 864605 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-471841-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Nms10aqE"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zQbLR1L9Hz9rxj for ; Tue, 23 Jan 2018 15:44:29 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=nA6VxYIcsDQjCKeiQWI3k/iWEyOLRz3whNKSYRXA/yNMok 7n6M9M9DQlKciiaggs8MdSjEJ475SE12/LBOnolkoYno/sGmC071mHfEKyxUJJzj zxiM2Gc+2RpiBvrBj0oMzmUCKovCR9tCz1B8Nk+9ev9LA2ivZC5EA6YJu9e3k= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=YTEoFyE9nZEM3F5RkG95TL99TO8=; b=Nms10aqEwdgK1Kuvry3E j20sWbJNWEXWewt7L6CNbvJcPIoMxLi2lg1aj5w0JnrOhWyiUQVVmFacDJyhfbUs wR5Ve/ChSFQooTKyO4FscpL2hVY5X1nKdJ58HBGWSBgMALbbdvqLAb0pV/eQ+rVl CHNEzsCAR65GKex37dXqVgc= Received: (qmail 48626 invoked by alias); 23 Jan 2018 04:44:21 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 48094 invoked by uid 89); 23 Jan 2018 04:44:20 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-wm0-f42.google.com Received: from mail-wm0-f42.google.com (HELO mail-wm0-f42.google.com) (74.125.82.42) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 23 Jan 2018 04:44:19 +0000 Received: by mail-wm0-f42.google.com with SMTP id b21so20924971wme.4 for ; Mon, 22 Jan 2018 20:44:18 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=wwzsCbuz7SNxtDjvhZMpzsPTVsuTLgCUpXvunx1eYok=; b=OEN+e6f3xxcoAlX5AA2GMv92Eokaw5FOjAPskXmb4nuuag740TLrW4beDQrTlsq1Mk vv12TxiLXDyPmiZi+sITOtmktRPDHhb81cg2ZJ9qu94WM5VjawII3JZlrWj5hGG/Hnw+ BwjDSDBx7yfwDrLMHotwbfAwSDwaMtkGKqOB8GUKmQuCss62m+53sVJPUywbDhhRTPy5 cBFk6XCHk9bgqGaVOJF+OTLvaucJV6NIs+X1HMvwl7ZWz0Gb4UneqVsOejwIhb0UbxXh BZegZnT7uRUSxSaVOn9i7/D1odi1GxZLnYbItD3wBNHazQlt3NFCqGXWpuPljH35OYrd epPA== X-Gm-Message-State: AKwxyteoIH15TIJ251FL9N0R4/rFpsmg9itRC9aendtqekQdne2Rm16X faPlDSEnggIYqhZS4J/xoTsDk1SvEPHoN1JWVhs8lQ== X-Google-Smtp-Source: AH8x224iNpwAWZGFlmT4lgV43iaM3uWtVLVirBUHb/jS8hB6xtwfHMWqhMHD7i6VPNAzSzCB8E+VWf9BHog+Q+4Ozhw= X-Received: by 10.80.215.146 with SMTP id w18mr17193330edi.208.1516682656786; Mon, 22 Jan 2018 20:44:16 -0800 (PST) MIME-Version: 1.0 Received: by 10.80.134.56 with HTTP; Mon, 22 Jan 2018 20:44:15 -0800 (PST) From: Ian Lance Taylor Date: Mon, 22 Jan 2018 20:44:15 -0800 Message-ID: Subject: libgo patch committed: Add buildid support for AIX To: gcc-patches , gofrontend-dev@googlegroups.com This patch by Tony Reix adds buildid support to the go tool for AIX. This supports caching of build results. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline. Ian Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 256877) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -87525458bcd5ab4beb5b95e7d58e3dfdbc1bd478 +3488a401e50835de5de5c4f153772ac2798d0e71 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: libgo/go/cmd/go/internal/work/buildid.go =================================================================== --- libgo/go/cmd/go/internal/work/buildid.go (revision 256794) +++ libgo/go/cmd/go/internal/work/buildid.go (working copy) @@ -330,6 +330,43 @@ func (b *Builder) gccgoBuildIDELFFile(a return sfile, nil } +// gccgoBuildIDXCOFFFile creates an assembler file that records the +// action's build ID in a CSECT (AIX linker deletes CSECTs that are +// not referenced in the output file). +func (b *Builder) gccgoBuildIDXCOFFFile(a *Action) (string, error) { + sfile := a.Objdir + "_buildid.s" + + var buf bytes.Buffer + fmt.Fprintf(&buf, "\t.csect .go.buildid[XO]\n") + fmt.Fprintf(&buf, "\t.byte ") + for i := 0; i < len(a.buildID); i++ { + if i > 0 { + if i%8 == 0 { + fmt.Fprintf(&buf, "\n\t.byte ") + } else { + fmt.Fprintf(&buf, ",") + } + } + fmt.Fprintf(&buf, "%#02x", a.buildID[i]) + } + fmt.Fprintf(&buf, "\n") + + if cfg.BuildN || cfg.BuildX { + for _, line := range bytes.Split(buf.Bytes(), []byte("\n")) { + b.Showcmd("", "echo '%s' >> %s", line, sfile) + } + if cfg.BuildN { + return sfile, nil + } + } + + if err := ioutil.WriteFile(sfile, buf.Bytes(), 0666); err != nil { + return "", err + } + + return sfile, nil +} + // buildID returns the build ID found in the given file. // If no build ID is found, buildID returns the content hash of the file. func (b *Builder) buildID(file string) string { Index: libgo/go/cmd/go/internal/work/exec.go =================================================================== --- libgo/go/cmd/go/internal/work/exec.go (revision 256873) +++ libgo/go/cmd/go/internal/work/exec.go (working copy) @@ -637,6 +637,16 @@ func (b *Builder) build(a *Action) (err return err } objects = append(objects, ofiles...) + case "aix": + asmfile, err := b.gccgoBuildIDXCOFFFile(a) + if err != nil { + return err + } + ofiles, err := BuildToolchain.asm(b, a, []string{asmfile}) + if err != nil { + return err + } + objects = append(objects, ofiles...) } } Index: libgo/go/cmd/internal/buildid/buildid.go =================================================================== --- libgo/go/cmd/internal/buildid/buildid.go (revision 256593) +++ libgo/go/cmd/internal/buildid/buildid.go (working copy) @@ -7,6 +7,7 @@ package buildid import ( "bytes" "debug/elf" + "debug/xcoff" "fmt" "io" "os" @@ -40,6 +41,9 @@ func ReadFile(name string) (id string, e return "", err } if string(buf) != "!\n" { + if string(buf) == "\n" { + return readGccgoBigArchive(name, f) + } return readBinary(name, f) } @@ -156,6 +160,85 @@ func readGccgoArchive(name string, f *os } } } + +// readGccgoBigArchive tries to parse the archive as an AIX big +// archive file, and fetch the build ID from the _buildid.o entry. +// The _buildid.o entry is written by (*Builder).gccgoBuildIDXCOFFFile +// in cmd/go/internal/work/exec.go. +func readGccgoBigArchive(name string, f *os.File) (string, error) { + bad := func() (string, error) { + return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} + } + + // Read fixed-length header. + if _, err := f.Seek(0, io.SeekStart); err != nil { + return "", err + } + var flhdr [128]byte + if _, err := io.ReadFull(f, flhdr[:]); err != nil { + return "", err + } + // Read first member offset. + offStr := strings.TrimSpace(string(flhdr[68:88])) + off, err := strconv.ParseInt(offStr, 10, 64) + if err != nil { + return bad() + } + for { + if off == 0 { + // No more entries, no build ID. + return "", nil + } + if _, err := f.Seek(off, io.SeekStart); err != nil { + return "", err + } + // Read member header. + var hdr [112]byte + if _, err := io.ReadFull(f, hdr[:]); err != nil { + return "", err + } + // Read member name length. + namLenStr := strings.TrimSpace(string(hdr[108:112])) + namLen, err := strconv.ParseInt(namLenStr, 10, 32) + if err != nil { + return bad() + } + if namLen == 10 { + var nam [10]byte + if _, err := io.ReadFull(f, nam[:]); err != nil { + return "", err + } + if string(nam[:]) == "_buildid.o" { + sizeStr := strings.TrimSpace(string(hdr[0:20])) + size, err := strconv.ParseInt(sizeStr, 10, 64) + if err != nil { + return bad() + } + off += int64(len(hdr)) + namLen + 2 + if off&1 != 0 { + off++ + } + sr := io.NewSectionReader(f, off, size) + x, err := xcoff.NewFile(sr) + if err != nil { + return bad() + } + data := x.CSect(".go.buildid") + if data == nil { + return bad() + } + return string(data), nil + } + } + + // Read next member offset. + offStr = strings.TrimSpace(string(hdr[20:40])) + off, err = strconv.ParseInt(offStr, 10, 64) + if err != nil { + return bad() + } + } +} var ( goBuildPrefix = []byte("\xff Go build ID: \"")